Merge branch 'version-12-hotfix' of https://github.com/frappe/frappe into google_calender
This commit is contained in:
commit
ee02c8a4ec
28 changed files with 372 additions and 174 deletions
103
.travis.yml
103
.travis.yml
|
|
@ -2,43 +2,88 @@ language: python
|
|||
dist: trusty
|
||||
sudo: required
|
||||
|
||||
python:
|
||||
- 2.7
|
||||
- 3.6
|
||||
|
||||
env:
|
||||
- DB=mariadb
|
||||
- DB=postgres
|
||||
- TEST_TYPE=ui
|
||||
|
||||
services:
|
||||
- mysql
|
||||
|
||||
addons:
|
||||
postgresql: "9.5"
|
||||
hosts:
|
||||
- test_site
|
||||
- test_site_postgres
|
||||
- test_site_ui
|
||||
mariadb: 10.3
|
||||
postgresql: 9.5
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
cache:
|
||||
- pip
|
||||
- npm
|
||||
- yarn
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- python: 2.7
|
||||
env: DB=postgres
|
||||
- python: 2.7
|
||||
env: TEST_TYPE=ui
|
||||
include:
|
||||
- name: "Python 3.6 MariaDB"
|
||||
python: 3.6
|
||||
env: DB=mariadb TYPE=server
|
||||
script: bench --site test_site run-tests --coverage
|
||||
|
||||
- name: "Python 3.6 PostgreSQL"
|
||||
python: 3.6
|
||||
env: DB=postgres TYPE=server
|
||||
script: bench --site test_site run-tests --coverage
|
||||
|
||||
- name: "Cypress"
|
||||
python: 3.6
|
||||
env: DB=mariadb TYPE=ui
|
||||
before_script: bench --site test_site execute frappe.utils.install.complete_setup_wizard
|
||||
script: bench --site test_site run-ui-tests frappe --headless
|
||||
|
||||
- name: "Python 2.7 MariaDB"
|
||||
python: 2.7
|
||||
env: DB=mariadb TYPE=server
|
||||
script: bench --site test_site run-tests --coverage
|
||||
|
||||
install:
|
||||
- $TRAVIS_BUILD_DIR/.travis/install.sh
|
||||
- cd ~
|
||||
- source ./.nvm/nvm.sh
|
||||
- nvm install v8.10.0
|
||||
|
||||
- git clone https://github.com/frappe/bench --depth 1
|
||||
- pip install -e ./bench
|
||||
|
||||
- bench init frappe-bench --skip-assets --python $(which python) --frappe-path $TRAVIS_BUILD_DIR
|
||||
|
||||
- mkdir ~/frappe-bench/sites/test_site
|
||||
- cp $TRAVIS_BUILD_DIR/.travis/$DB.json ~/frappe-bench/sites/test_site/site_config.json
|
||||
|
||||
- mysql -u root -e "SET GLOBAL character_set_server = 'utf8mb4'"
|
||||
- mysql -u root -e "SET GLOBAL collation_server = 'utf8mb4_unicode_ci'"
|
||||
|
||||
- mysql -u root -e "CREATE DATABASE test_frappe"
|
||||
- mysql -u root -e "CREATE USER 'test_frappe'@'localhost' IDENTIFIED BY 'test_frappe'"
|
||||
- mysql -u root -e "GRANT ALL PRIVILEGES ON \`test_frappe\`.* TO 'test_frappe'@'localhost'"
|
||||
|
||||
- mysql -u root -e "UPDATE mysql.user SET Password=PASSWORD('travis') WHERE User='root'"
|
||||
- mysql -u root -e "FLUSH PRIVILEGES"
|
||||
|
||||
- psql -c "CREATE DATABASE test_frappe" -U postgres
|
||||
- psql -c "CREATE USER test_frappe WITH PASSWORD 'test_frappe'" -U postgres
|
||||
|
||||
- wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
|
||||
- tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
|
||||
- sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
|
||||
- sudo chmod o+x /usr/local/bin/wkhtmltopdf
|
||||
|
||||
- cd ./frappe-bench
|
||||
|
||||
- sed -i 's/watch:/# watch:/g' Procfile
|
||||
- sed -i 's/schedule:/# schedule:/g' Procfile
|
||||
|
||||
- if [ $TYPE == "server" ]; then sed -i 's/socketio:/# socketio:/g' Procfile; fi
|
||||
- if [ $TYPE == "server" ]; then sed -i 's/redis_socketio:/# redis_socketio:/g' Procfile; fi
|
||||
|
||||
- if [ $TYPE == "ui" ]; then bench setup requirements --node; fi
|
||||
|
||||
before_script:
|
||||
- cd ~/frappe-bench
|
||||
- sed -i 's/9000/9001/g' sites/common_site_config.json
|
||||
- bench start &
|
||||
- sleep 10
|
||||
|
||||
script:
|
||||
- $TRAVIS_BUILD_DIR/.travis/run-tests.sh
|
||||
- bench --site test_site reinstall --yes
|
||||
- bench build --app frappe
|
||||
|
||||
after_script:
|
||||
- coveralls -b apps/frappe -d ../../sites/.coverage
|
||||
- pip install python-coveralls
|
||||
- coveralls -b apps/frappe -d ../../sites/.coverage
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
sudo rm /etc/apt/sources.list.d/mongodb*.list
|
||||
sudo rm /etc/apt/sources.list.d/docker.list
|
||||
sudo apt-get install hhvm && rm -rf /home/travis/.kiex/
|
||||
sudo apt-get purge -y mysql-common mysql-server mysql-client
|
||||
source ~/.nvm/nvm.sh
|
||||
nvm install v8.10.0
|
||||
|
||||
pip install python-coveralls
|
||||
|
||||
wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
|
||||
|
||||
sudo python install.py --develop --user travis --without-bench-setup
|
||||
sudo pip install -e ~/bench
|
||||
|
||||
rm $TRAVIS_BUILD_DIR/.git/shallow
|
||||
cd ~/ && bench init frappe-bench --python $(which python) --frappe-path $TRAVIS_BUILD_DIR
|
||||
if [[ $DB == 'mariadb' ]]; then
|
||||
cp -r $TRAVIS_BUILD_DIR/test_sites/test_site ~/frappe-bench/sites/
|
||||
elif [[ $TEST_TYPE == 'ui' ]]; then
|
||||
cp -r $TRAVIS_BUILD_DIR/test_sites/test_site_ui ~/frappe-bench/sites/
|
||||
elif [[ $DB == 'postgres' ]]; then
|
||||
cp -r $TRAVIS_BUILD_DIR/test_sites/test_site_postgres ~/frappe-bench/sites/
|
||||
fi
|
||||
14
.travis/mariadb.json
Normal file
14
.travis/mariadb.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"db_host": "localhost",
|
||||
"db_name": "test_frappe",
|
||||
"db_password": "test_frappe",
|
||||
"db_type": "mariadb",
|
||||
"auto_email_id": "test@example.com",
|
||||
"mail_server": "smtp.example.com",
|
||||
"mail_login": "test@example.com",
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_login": "root",
|
||||
"root_password": "travis",
|
||||
"host_name": "http://test_site:8000"
|
||||
}
|
||||
14
.travis/postgres.json
Normal file
14
.travis/postgres.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"db_host": "localhost",
|
||||
"db_name": "test_frappe",
|
||||
"db_password": "test_frappe",
|
||||
"db_type": "postgres",
|
||||
"auto_email_id": "test@example.com",
|
||||
"mail_server": "smtp.example.com",
|
||||
"mail_login": "test@example.com",
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_login": "postgres",
|
||||
"root_password": "travis",
|
||||
"host_name": "http://test_site:8000"
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
setup_mariadb_env() {
|
||||
mysql -u root -ptravis -e "create database $1"
|
||||
mysql -u root -ptravis -e "USE mysql; CREATE USER '$1'@'localhost' IDENTIFIED BY '$1'; FLUSH PRIVILEGES; "
|
||||
mysql -u root -ptravis -e "USE mysql; GRANT ALL PRIVILEGES ON \`$1\`.* TO '$1'@'localhost';"
|
||||
}
|
||||
|
||||
if [[ $DB == 'mariadb' ]]; then
|
||||
setup_mariadb_env 'test_frappe'
|
||||
bench --site test_site reinstall --yes
|
||||
bench --site test_site scheduler disable
|
||||
bench --site test_site run-tests --coverage
|
||||
|
||||
elif [[ $TEST_TYPE == 'ui' ]]; then
|
||||
setup_mariadb_env 'test_site_ui'
|
||||
bench --site test_site_ui reinstall --yes
|
||||
bench --site test_site_ui execute frappe.utils.install.complete_setup_wizard
|
||||
bench --site test_site_ui scheduler disable
|
||||
cd apps/frappe && yarn && yarn cypress:run
|
||||
|
||||
elif [[ $DB == 'postgres' ]]; then
|
||||
psql -c "CREATE DATABASE test_frappe;" -U postgres
|
||||
psql -c "CREATE USER test_frappe WITH PASSWORD 'test_frappe';" -U postgres
|
||||
bench --site test_site_postgres reinstall --yes
|
||||
bench --site test_site_postgres scheduler disable
|
||||
bench --site test_site_postgres run-tests --coverage
|
||||
fi
|
||||
|
|
@ -1,29 +1,29 @@
|
|||
# Version 12 Release Notes
|
||||
|
||||
### UI/UX Enhancements
|
||||
1. [New Desktop](/docs/user/manual/en/using-erpnext/desktop)
|
||||
1. [Keyboard Navigation](/docs/user/manual/en/using-erpnext/articles/keyboard-shortcuts)
|
||||
1. [Link Preview](/version-12/release-notes/features#link-preview)
|
||||
1. [New Upload Dialog](/version-12/release-notes/features#new-upload-dialog)
|
||||
1. [Frequently visited links appear in Awesomebar results](/version-12/release-notes/features#frequently-visited-links-appear-in-awesomebar-results)
|
||||
1. [Full Width Container]((/version-12/release-notes/features#full-width-container))
|
||||
1. [List View Enhancements](/version-12/release-notes/features#list-view-enhancements)
|
||||
1. [New Desktop](https://erpnext.com/docs/user/manual/en/using-erpnext/desktop)
|
||||
1. [Keyboard Navigation](https://erpnext.com/docs/user/manual/en/using-erpnext/articles/keyboard-shortcuts)
|
||||
1. [Link Preview](https://erpnext.com/version-12/release-notes/features#link-preview)
|
||||
1. [New Upload Dialog](https://erpnext.com/version-12/release-notes/features#new-upload-dialog)
|
||||
1. [Frequently visited links appear in Awesomebar results](https://erpnext.com/version-12/release-notes/features#frequently-visited-links-appear-in-awesomebar-results)
|
||||
1. [Full Width Container]((https://erpnext.com/version-12/release-notes/features#full-width-container))
|
||||
1. [List View Enhancements](https://erpnext.com/version-12/release-notes/features#list-view-enhancements)
|
||||
|
||||
### New Automation Module
|
||||
1. [Assignment Rule](/docs/user/manual/en/setting-up/automation/assignment-rule)
|
||||
1. [Milestones](/docs/user/manual/en/setting-up/automation/milestone-tracker)
|
||||
1. [Auto Repeat](/docs/user/manual/en/setting-up/automation/auto-repeat)
|
||||
1. [Assignment Rule](https://erpnext.com/docs/user/manual/en/setting-up/automation/assignment-rule)
|
||||
1. [Milestones](https://erpnext.com/docs/user/manual/en/setting-up/automation/milestone-tracker)
|
||||
1. [Auto Repeat](https://erpnext.com/docs/user/manual/en/setting-up/automation/auto-repeat)
|
||||
|
||||
### Other Changes & Enhancements
|
||||
1. [Document Follow](/docs/user/manual/en/setting-up/email/document-follow)
|
||||
1. [Energy Points](/docs/user/manual/en/setting-up/energy-point-system)
|
||||
1. [Dashboards](/docs/user/manual/en/customize-erpnext/dashboard)
|
||||
1. [Disable customization for single doctypes](/version-12/release-notes/features#disable-customization-for-single-doctypes)
|
||||
1. [Email Linking](/docs/user/manual/en/setting-up/email/linking-emails-to-document)
|
||||
1. [Google Contacts](/docs/user/manual/en/erpnext_integration/google_contacts)
|
||||
1. [PDF Encryption](/version-12/release-notes/features#pdf-encryption)
|
||||
1. [Raw Printing](/docs/user/manual/en/setting-up/print/raw-printing)
|
||||
1. [Web Form Refactor](/version-12/release-notes/features#web-form-refactor)
|
||||
1. [Website Refactor](/docs/user/manual/en/website)
|
||||
1. [Added Track Views field to Customize Form](/version-12/release-notes/features#added-track-views-field-to-customize-form)
|
||||
1. [Add custom columns to any report](/version-12/release-notes/features#add-custom-columns-to-any-report)
|
||||
1. [Document Follow](https://erpnext.com/docs/user/manual/en/setting-up/email/document-follow)
|
||||
1. [Energy Points](https://erpnext.com/docs/user/manual/en/setting-up/energy-point-system)
|
||||
1. [Dashboards](https://erpnext.com/docs/user/manual/en/customize-erpnext/dashboard)
|
||||
1. [Disable customization for single doctypes](https://erpnext.com/version-12/release-notes/features#disable-customization-for-single-doctypes)
|
||||
1. [Email Linking](https://erpnext.com/docs/user/manual/en/setting-up/email/linking-emails-to-document)
|
||||
1. [Google Contacts](https://erpnext.com/docs/user/manual/en/erpnext_integration/google_contacts)
|
||||
1. [PDF Encryption](https://erpnext.com/version-12/release-notes/features#pdf-encryption)
|
||||
1. [Raw Printing](https://erpnext.com/docs/user/manual/en/setting-up/print/raw-printing)
|
||||
1. [Web Form Refactor](https://erpnext.com/version-12/release-notes/features#web-form-refactor)
|
||||
1. [Website Refactor](https://erpnext.com/docs/user/manual/en/website)
|
||||
1. [Added Track Views field to Customize Form](https://erpnext.com/version-12/release-notes/features#added-track-views-field-to-customize-form)
|
||||
1. [Add custom columns to any report](https://erpnext.com/version-12/release-notes/features#add-custom-columns-to-any-report)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ def popen(command, *args, **kwargs):
|
|||
|
||||
return_ = proc.wait()
|
||||
|
||||
if raise_err:
|
||||
if return_ and raise_err:
|
||||
raise subprocess.CalledProcessError(return_, command)
|
||||
|
||||
return return_
|
||||
|
|
|
|||
|
|
@ -220,8 +220,9 @@ def disable_user(context, email):
|
|||
|
||||
@click.command('migrate')
|
||||
@click.option('--rebuild-website', help="Rebuild webpages after migration")
|
||||
@click.option('--skip-failing', is_flag=True, help="Skip patches that fail to run")
|
||||
@pass_context
|
||||
def migrate(context, rebuild_website=False):
|
||||
def migrate(context, rebuild_website=False, skip_failing=False):
|
||||
"Run patches, sync schema and rebuild files/translations"
|
||||
from frappe.migrate import migrate
|
||||
|
||||
|
|
@ -230,7 +231,7 @@ def migrate(context, rebuild_website=False):
|
|||
frappe.init(site=site)
|
||||
frappe.connect()
|
||||
try:
|
||||
migrate(context.verbose, rebuild_website=rebuild_website)
|
||||
migrate(context.verbose, rebuild_website=rebuild_website, skip_failing=skip_failing)
|
||||
finally:
|
||||
frappe.destroy()
|
||||
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ def run_ui_tests(context, app, headless=False):
|
|||
run_or_open = 'run' if headless else 'open'
|
||||
command = '{site_env} {password_env} yarn run cypress {run_or_open}'
|
||||
formatted_command = command.format(site_env=site_env, password_env=password_env, run_or_open=run_or_open)
|
||||
frappe.commands.popen(formatted_command, cwd=app_base_path)
|
||||
frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
|
||||
|
||||
@click.command('run-setup-wizard-ui-test')
|
||||
@click.option('--app', help="App to run tests on, leave blank for all apps")
|
||||
|
|
|
|||
|
|
@ -188,14 +188,20 @@ class File(NestedSet):
|
|||
# check duplicate name
|
||||
|
||||
# check duplicate assignement
|
||||
n_records = frappe.db.sql("""select name from `tabFile`
|
||||
where content_hash=%s
|
||||
and name!=%s
|
||||
and attached_to_doctype=%s
|
||||
and attached_to_name=%s""", (self.content_hash, self.name, self.attached_to_doctype,
|
||||
self.attached_to_name))
|
||||
if len(n_records) > 0:
|
||||
self.duplicate_entry = n_records[0][0]
|
||||
filters = {
|
||||
'content_hash': self.content_hash,
|
||||
'is_private': self.is_private,
|
||||
'name': ('!=', self.name)
|
||||
}
|
||||
if self.attached_to_doctype and self.attached_to_name:
|
||||
filters.update({
|
||||
'attached_to_doctype': self.attached_to_doctype,
|
||||
'attached_to_name': self.attached_to_name
|
||||
})
|
||||
duplicate_file = frappe.db.get_value('File', filters)
|
||||
|
||||
if duplicate_file:
|
||||
self.duplicate_entry = duplicate_file
|
||||
frappe.throw(_("Same file has already been attached to the record"),
|
||||
frappe.DuplicateEntryError)
|
||||
|
||||
|
|
@ -451,7 +457,7 @@ class File(NestedSet):
|
|||
return
|
||||
|
||||
self.file_url = unquote(self.file_url)
|
||||
self.file_size = frappe.form_dict.file_size
|
||||
self.file_size = frappe.form_dict.file_size or self.file_size
|
||||
|
||||
|
||||
def get_uploaded_content(self):
|
||||
|
|
@ -484,7 +490,13 @@ class File(NestedSet):
|
|||
self.content_hash = get_content_hash(self.content)
|
||||
self.content_type = mimetypes.guess_type(self.file_name)[0]
|
||||
|
||||
_file = frappe.get_value("File", {"content_hash": self.content_hash}, ["file_url"])
|
||||
# check if a file exists with the same content hash and is also in the same folder (public or private)
|
||||
_file = frappe.get_value("File", {
|
||||
"content_hash": self.content_hash,
|
||||
"is_private": self.is_private
|
||||
},
|
||||
["file_url"])
|
||||
|
||||
if _file:
|
||||
self.file_url = _file
|
||||
file_exists = True
|
||||
|
|
|
|||
29
frappe/core/doctype/session_default/session_default.json
Normal file
29
frappe/core/doctype/session_default/session_default.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"creation": "2019-07-17 16:21:33.546379",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"ref_doctype"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "ref_doctype",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Document Type",
|
||||
"options": "DocType"
|
||||
}
|
||||
],
|
||||
"istable": 1,
|
||||
"modified": "2019-07-21 13:22:25.752553",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Session Default",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
10
frappe/core/doctype/session_default/session_default.py
Normal file
10
frappe/core/doctype/session_default/session_default.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class SessionDefault(Document):
|
||||
pass
|
||||
0
frappe/core/doctype/session_default_settings/__init__.py
Normal file
0
frappe/core/doctype/session_default_settings/__init__.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"creation": "2019-07-17 16:22:31.300991",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"session_defaults"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "session_defaults",
|
||||
"fieldtype": "Table",
|
||||
"label": "Session Defaults",
|
||||
"options": "Session Default"
|
||||
}
|
||||
],
|
||||
"issingle": 1,
|
||||
"modified": "2019-07-19 16:04:33.971089",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Session Default Settings",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
import json
|
||||
from frappe.model.document import Document
|
||||
|
||||
class SessionDefaultSettings(Document):
|
||||
pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_session_default_values():
|
||||
settings = frappe.get_single('Session Default Settings')
|
||||
fields = []
|
||||
for default_values in settings.session_defaults:
|
||||
reference_doctype = frappe.scrub(default_values.ref_doctype)
|
||||
fields.append({
|
||||
'fieldname': reference_doctype,
|
||||
'fieldtype': 'Link',
|
||||
'options': default_values.ref_doctype,
|
||||
'label': _('Default {0}').format(_(default_values.ref_doctype)),
|
||||
'default': frappe.defaults.get_user_default(reference_doctype)
|
||||
})
|
||||
return json.dumps(fields)
|
||||
|
||||
@frappe.whitelist()
|
||||
def set_session_default_values(default_values):
|
||||
if not frappe.flags.in_test:
|
||||
default_values = json.loads(default_values)
|
||||
for entry in default_values:
|
||||
try:
|
||||
frappe.defaults.set_user_default(entry, default_values.get(entry))
|
||||
except Exception:
|
||||
return
|
||||
return "success"
|
||||
|
||||
#called on hook 'on_logout' to clear defaults for the session
|
||||
def clear_session_defaults():
|
||||
settings = frappe.get_single('Session Default Settings').session_defaults
|
||||
for entry in settings:
|
||||
frappe.defaults.clear_user_default(frappe.scrub(entry.ref_doctype))
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2019, Frappe Technologies and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.core.doctype.session_default_settings.session_default_settings import set_session_default_values, clear_session_defaults
|
||||
|
||||
class TestSessionDefaultSettings(unittest.TestCase):
|
||||
def test_set_session_default_settings(self):
|
||||
frappe.set_user("Administrator")
|
||||
settings = frappe.get_single("Session Default Settings")
|
||||
settings.session_defaults = []
|
||||
settings.append("session_defaults", {
|
||||
"ref_doctype": "Role"
|
||||
})
|
||||
settings.save()
|
||||
|
||||
set_session_default_values({"role": "Website Manager"})
|
||||
|
||||
todo = frappe.get_doc(dict(doctype="ToDo", description="test session defaults set", assigned_by="Administrator")).insert()
|
||||
self.assertEqual(todo.role, "Website Manager")
|
||||
|
||||
def test_clear_session_defaults(self):
|
||||
clear_session_defaults()
|
||||
todo = frappe.get_doc(dict(doctype="ToDo", description="test session defaults cleared", assigned_by="Administrator")).insert()
|
||||
self.assertNotEqual(todo.role, "Website Manager")
|
||||
|
|
@ -252,4 +252,4 @@ def get_view_logs(doctype, docname):
|
|||
|
||||
if view_logs:
|
||||
logs = view_logs
|
||||
return logs
|
||||
return logs
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ on_session_creation = [
|
|||
"frappe.utils.scheduler.reset_enabled_scheduler_events",
|
||||
]
|
||||
|
||||
on_logout = "frappe.core.doctype.session_default_settings.session_default_settings.clear_session_defaults"
|
||||
|
||||
# permissions
|
||||
|
||||
permission_query_conditions = {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from frappe.core.doctype.language.language import sync_languages
|
|||
from frappe.modules.utils import sync_customizations
|
||||
from frappe.utils import global_search
|
||||
|
||||
def migrate(verbose=True, rebuild_website=False):
|
||||
def migrate(verbose=True, rebuild_website=False, skip_failing=False):
|
||||
'''Migrate all apps to the latest version, will:
|
||||
- run before migrate hooks
|
||||
- run patches
|
||||
|
|
@ -45,7 +45,7 @@ def migrate(verbose=True, rebuild_website=False):
|
|||
frappe.get_attr(fn)()
|
||||
|
||||
# run patches
|
||||
frappe.modules.patch_handler.run_all()
|
||||
frappe.modules.patch_handler.run_all(skip_failing)
|
||||
# sync
|
||||
frappe.model.sync.sync_all(verbose=verbose)
|
||||
frappe.translate.clear_cache()
|
||||
|
|
|
|||
|
|
@ -175,10 +175,11 @@ class BaseDocument(object):
|
|||
if not self.doctype:
|
||||
return value
|
||||
if not isinstance(value, BaseDocument):
|
||||
if "doctype" not in value:
|
||||
if "doctype" not in value or value['doctype'] is None:
|
||||
value["doctype"] = self.get_table_field_doctype(key)
|
||||
if not value["doctype"]:
|
||||
raise AttributeError(key)
|
||||
|
||||
value = get_controller(value["doctype"])(value)
|
||||
value.init_valid_columns()
|
||||
|
||||
|
|
|
|||
|
|
@ -19,23 +19,31 @@ import os
|
|||
|
||||
class PatchError(Exception): pass
|
||||
|
||||
def run_all():
|
||||
def run_all(skip_failing=False):
|
||||
"""run all pending patches"""
|
||||
executed = [p[0] for p in frappe.db.sql("""select patch from `tabPatch Log`""")]
|
||||
|
||||
frappe.flags.final_patches = []
|
||||
for patch in get_all_patches():
|
||||
if patch and (patch not in executed):
|
||||
|
||||
def run_patch(patch):
|
||||
try:
|
||||
if not run_single(patchmodule = patch):
|
||||
log(patch + ': failed: STOPPED')
|
||||
raise PatchError(patch)
|
||||
except Exception:
|
||||
if not skip_failing:
|
||||
raise
|
||||
else:
|
||||
log('Failed to execute patch')
|
||||
|
||||
for patch in get_all_patches():
|
||||
if patch and (patch not in executed):
|
||||
run_patch(patch)
|
||||
|
||||
# patches to be run in the end
|
||||
for patch in frappe.flags.final_patches:
|
||||
patch = patch.replace('finally:', '')
|
||||
if not run_single(patchmodule = patch):
|
||||
log(patch + ': failed: STOPPED')
|
||||
raise PatchError(patch)
|
||||
run_patch(patch)
|
||||
|
||||
def get_all_patches():
|
||||
patches = []
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
{%= __("My Profile") %}</a></li>
|
||||
<li><a href="#Form/User/{%= encodeURIComponent(frappe.session.user) %}">
|
||||
{%= __("My Settings") %}</a></li>
|
||||
<li><a href="#" onclick="return frappe.ui.toolbar.setup_session_defaults();">
|
||||
{%= __("Session Defaults") %}</a></li>
|
||||
<li class="navbar-reload">
|
||||
<a href="#" onclick="return frappe.ui.toolbar.clear_cache();">
|
||||
{%= __("Reload") %}</a></li>
|
||||
|
|
|
|||
|
|
@ -235,3 +235,50 @@ frappe.ui.toolbar.show_about = function() {
|
|||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
frappe.ui.toolbar.setup_session_defaults = function() {
|
||||
let fields = [];
|
||||
frappe.call({
|
||||
method: 'frappe.core.doctype.session_default_settings.session_default_settings.get_session_default_values',
|
||||
callback: function (data) {
|
||||
fields = JSON.parse(data.message);
|
||||
let perms = frappe.perm.get_perm('Session Default Settings');
|
||||
//add settings button only if user is a System Manager or has permission on 'Session Default Settings'
|
||||
if ((in_list(frappe.user_roles, 'System Manager')) || (perms[0].read == 1)) {
|
||||
fields[fields.length] = {
|
||||
'fieldname': 'settings',
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Settings'),
|
||||
'click': () => {
|
||||
frappe.set_route('Form', 'Session Default Settings', 'Session Default Settings');
|
||||
}
|
||||
};
|
||||
}
|
||||
frappe.prompt(fields, function(values) {
|
||||
frappe.call({
|
||||
method: 'frappe.core.doctype.session_default_settings.session_default_settings.set_session_default_values',
|
||||
args: {
|
||||
default_values: values,
|
||||
},
|
||||
callback: function(data) {
|
||||
if (data.message == "success") {
|
||||
frappe.show_alert({
|
||||
'message': __('Session Defaults Saved'),
|
||||
'indicator': 'green'
|
||||
});
|
||||
frappe.clear_cache();
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
'message': __('An error occurred while setting Session Defaults'),
|
||||
'indicator': 'red'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
__('Session Defaults'),
|
||||
__('Save'),
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def render_template(template, context, is_path=None, safe_render=True):
|
|||
or (template.endswith('.html') and '\n' not in template)):
|
||||
return get_jenv().get_template(template).render(context)
|
||||
else:
|
||||
if safe_render and ".__" in template:
|
||||
if safe_render and "__" in template:
|
||||
throw("Illegal template")
|
||||
try:
|
||||
return get_jenv().from_string(template).render(context)
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"db_name": "test_frappe",
|
||||
"db_password": "test_frappe",
|
||||
"auto_email_id": "test@example.com",
|
||||
"mail_server": "smtp.example.com",
|
||||
"mail_login": "test@example.com",
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_password": "travis",
|
||||
"run_selenium_tests": 1,
|
||||
"host_name": "http://test_site:8000"
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"db_host": "localhost",
|
||||
"db_name": "test_frappe",
|
||||
"db_password": "test_frappe",
|
||||
"db_type": "postgres",
|
||||
"auto_email_id": "test@example.com",
|
||||
"mail_server": "smtp.example.com",
|
||||
"mail_login": "test@example.com",
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_login": "postgres",
|
||||
"root_password": "travis",
|
||||
"run_selenium_tests": 1,
|
||||
"host_name": "http://test_site_postgres:8000"
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"developer_mode": 1,
|
||||
"db_name": "test_site_ui",
|
||||
"db_password": "test_site_ui",
|
||||
"db_type": "mariadb",
|
||||
"auto_email_id": "test@example.com",
|
||||
"mail_server": "smtp.example.com",
|
||||
"mail_login": "test@example.com",
|
||||
"mail_password": "test",
|
||||
"admin_password": "admin",
|
||||
"root_password": "travis",
|
||||
"run_selenium_tests": 1,
|
||||
"host_name": "http://test_site_ui:8000"
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue