Commit f2bc961e authored by Nabin Hait's avatar Nabin Hait
Browse files

Fixed merge conflict

parents 4b231108 26507591
develop v11.1.5 v11.1.4 v11.1.3 v11.1.2 v11.1.1 v11.1.0 v11.0.3 v11.0.3-beta.51 v11.0.3-beta.50 v11.0.3-beta.49 v11.0.3-beta.48 v11.0.3-beta.47 v11.0.3-beta.46 v11.0.3-beta.45 v11.0.3-beta.44 v11.0.3-beta.43 v11.0.3-beta.42 v11.0.3-beta.41 v11.0.3-beta.40 v11.0.3-beta.39 v11.0.3-beta.38 v11.0.3-beta.37 v11.0.3-beta.36 v11.0.3-beta.35 v11.0.3-beta.34 v11.0.3-beta.33 v11.0.3-beta.32 v11.0.3-beta.31 v11.0.3-beta.30 v11.0.3-beta.29 v11.0.3-beta.28 v11.0.3-beta.27 v11.0.3-beta.26 v11.0.3-beta.25 v11.0.3-beta.24 v11.0.3-beta.23 v11.0.3-beta.22 v11.0.3-beta.21 v11.0.3-beta.20 v11.0.3-beta.19 v11.0.3-beta.18 v11.0.3-beta.17 v11.0.3-beta.16 v11.0.3-beta.15 v11.0.3-beta.14 v11.0.3-beta.13 v11.0.3-beta.12 v11.0.3-beta.11 v11.0.3-beta.10 v11.0.3-beta.9 v11.0.3-beta.8 v11.0.3-beta.7 v11.0.3-beta.6 v11.0.3-beta.5 v11.0.3-beta.4 v11.0.3-beta.3 v11.0.3-beta.2 v11.0.3-beta.1 v11.0.2 v11.0.1 v11.0.0-beta v10.1.71 v10.1.70 v10.1.69 v10.1.68 v10.1.67 v10.1.66 v10.1.65 v10.1.64 v10.1.63 v10.1.62 v10.1.61 v10.1.60 v10.1.59 v10.1.58 v10.1.57 v10.1.56 v10.1.55 v10.1.54 v10.1.53 v10.1.52 v10.1.51 v10.1.50 v10.1.49 v10.1.49-beta.1 v10.1.48 v10.1.47 v10.1.46 v10.1.45 v10.1.44 v10.1.43 v10.1.42 v10.1.41 v10.1.40 v10.1.39 v10.1.38 v10.1.37 v10.1.36 v10.1.35 v10.1.34 v10.1.33 v10.1.32 v10.1.31 v10.1.30 v10.1.29 v10.1.28 v10.1.27 v10.1.26 v10.1.25 v10.1.24 v10.1.23 v10.1.22 v10.1.21 v10.1.20 v10.1.19 v10.1.18 v10.1.17 v10.1.16 v10.1.15 v10.1.14 v10.1.13 v10.1.12 v10.1.11 v10.1.10 v10.1.9 v10.1.8 v10.1.7 v10.1.6 v10.1.5 v10.1.4 v10.1.3 v10.1.2 v10.1.1 v10.1.0 v10.0.25 v10.0.24 v10.0.23 v10.0.22 v10.0.21 v10.0.20 v10.0.19 v10.0.18 v10.0.17 v10.0.16 v10.0.15 v10.0.14 v10.0.13 v10.0.12 v10.0.11 v10.0.10 v10.0.9 v10.0.8 v10.0.7 v10.0.6 v10.0.5 v10.0.4 v10.0.3 v10.0.2 v10.0.1 v10.0.0 v9.2.25 v9.2.24 v9.2.23 v9.2.22 v9.2.21 v9.2.20 v9.2.19 v9.2.18 v9.2.17 v9.2.16 v9.2.15 v9.2.14 v9.2.13 v9.2.12 v9.2.11 v9.2.10 v9.2.9 v9.2.8 v9.2.7 v9.2.6 v9.2.5 v9.2.4 v9.2.3 v9.2.2 v9.2.1 v9.2.0 v9.1.11 v9.1.10 v9.1.9 v9.1.8 v9.1.7 v9.1.6 v9.1.5 v9.1.4 v9.1.3 v9.1.2 v9.1.1 v9.1.0 v9.0.10 v9.0.9 v9.0.8 v9.0.7 v9.0.6 v9.0.5 v9.0.4 v9.0.3 v9.0.2 v9.0.1 v9.0.0 v8.10.9 v8.10.8 v8.10.7 v8.10.6 v8.10.5 v8.10.4 v8.10.3 v8.10.2 v8.10.1 v8.10.0 v8.9.4 v8.9.3 v8.9.2 v8.9.1 v8.9.0 v8.8.5 v8.8.4 v8.8.3 v8.8.2 v8.8.1 v8.8.0 v8.7.11 v8.7.10 v8.7.9 v8.7.8 v8.7.7 v8.7.6 v8.7.5 v8.7.4 v8.7.3 v8.7.2 v8.7.1 v8.7.0 v8.6.8 v8.6.7 v8.6.6 v8.6.5 v8.6.4 v8.6.3 v8.6.2 v8.6.1 v8.6.0 v8.5.8 v8.5.7 v8.5.6 v8.5.5 v8.5.4 v8.5.3 v8.5.2 v8.5.1 v8.5.0 v8.4.1 v8.4.0 v8.3.10 v8.3.9 v8.3.8 v8.3.7 v8.3.6 v8.3.5 v8.3.4 v8.3.3 v8.3.2 v8.3.1 v8.3.0 v8.2.7 v8.2.6 v8.2.5 v8.2.4 v8.2.3 v8.2.2 v8.2.1 v8.2.0 v8.1.4 v8.1.3 v8.1.2 v8.1.1 v8.1.0 v8.0.71 v8.0.70 v8.0.69 v8.0.68 v8.0.67 v8.0.66 v8.0.65 v8.0.64 v8.0.63 v8.0.62 v8.0.61 v8.0.60 v8.0.59 v8.0.58 v8.0.57 v8.0.56 v8.0.55 v8.0.54 v8.0.53 v8.0.52 v8.0.51 v8.0.50 v8.0.49 v8.0.48 v8.0.47 v8.0.46 v8.0.45 v8.0.44 v8.0.43 v8.0.42 v8.0.41 v8.0.40 v8.0.39 v8.0.38 v8.0.37 v8.0.36 v8.0.35 v8.0.34 v8.0.33 v8.0.32 v8.0.31 v8.0.30 v8.0.29 v8.0.28 v8.0.27 v8.0.26 v8.0.25 v8.0.24 v8.0.23 v8.0.22 v8.0.21 v8.0.20 v8.0.19 v8.0.18 v8.0.17 v8.0.16 v8.0.15 v8.0.14 v8.0.13 v8.0.12 v8.0.11 v8.0.10 v8.0.9 v8.0.8 v8.0.7 v8.0.6 v8.0.5 v8.0.4 v8.0.3 v8.0.2 v8.0.1 v8.0.0 v7.2.31 v7.2.30 v7.2.29 v7.2.28 v7.2.27 v7.2.26 v7.2.25 v7.2.24 v7.2.23 v7.2.22 v7.2.21 v7.2.20 v7.2.19 v7.2.18 v7.2.17 v7.2.16 v7.2.15 v7.2.14 v7.2.13 v7.2.12 v7.2.11 v7.2.10 v7.2.9 v7.2.8 v7.2.7 v7.2.6 v7.2.5 v7.2.4 v7.2.3 v7.2.2 v7.2.1 v7.2.0
No related merge requests found
Showing with 1666 additions and 1093 deletions
+1666 -1093
......@@ -41,16 +41,26 @@ class _dict(dict):
def _(msg, lang=None):
"""Returns translated string in current lang, if exists."""
from frappe.translate import get_full_dict
from frappe.utils import cstr
if not lang:
lang = local.lang
# msg should always be unicode
msg = cstr(msg).strip()
msg = as_unicode(msg).strip()
return get_full_dict(local.lang).get(msg) or msg
def as_unicode(text, encoding='utf-8'):
'''Convert to unicode if required'''
if isinstance(text, unicode):
return text
elif text==None:
return ''
elif isinstance(text, basestring):
return unicode(text, encoding)
else:
return unicode(text)
def get_lang_dict(fortype, name=None):
"""Returns the translated language dict for the given type and name.
......@@ -225,11 +235,11 @@ def errprint(msg):
"""Log error. This is sent back as `exc` in response.
:param msg: Message."""
from utils import cstr
msg = as_unicode(msg)
if not request or (not "cmd" in local.form_dict):
print cstr(msg)
print msg.encode('utf-8')
error_log.append(cstr(msg))
error_log.append(msg)
def log(msg):
"""Add to `debug_log`.
......@@ -239,8 +249,7 @@ def log(msg):
if conf.get("logging") or False:
print repr(msg)
from utils import cstr
debug_log.append(cstr(msg))
debug_log.append(as_unicode(msg))
def msgprint(msg, title=None, raise_exception=0, as_table=False, indicator=None, alert=False):
"""Print a message to the user (via HTTP response).
......@@ -355,12 +364,12 @@ def get_request_header(key, default=None):
:param default: Default value."""
return request.headers.get(key, default)
def sendmail(recipients=(), sender="", subject="No Subject", message="No Message",
def sendmail(recipients=[], sender="", subject="No Subject", message="No Message",
as_markdown=False, delayed=True, reference_doctype=None, reference_name=None,
unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
attachments=None, content=None, doctype=None, name=None, reply_to=None,
cc=(), show_as_cc=(), message_id=None, in_reply_to=None, send_after=None, expose_recipients=False,
send_priority=1, communication=None, retry=1):
cc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None,
send_priority=1, communication=None, retry=1, now=None):
"""Send email using user's default **Email Account** or global default **Email Account**.
......@@ -383,25 +392,23 @@ def sendmail(recipients=(), sender="", subject="No Subject", message="No Message
:param expose_recipients: Display all recipients in the footer message - "This email was sent to"
:param communication: Communication link to be set in Email Queue record
"""
message = content or message
if delayed:
import frappe.email.queue
frappe.email.queue.send(recipients=recipients, sender=sender,
subject=subject, message=content or message,
reference_doctype = doctype or reference_doctype, reference_name = name or reference_name,
unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
attachments=attachments, reply_to=reply_to, cc=cc, show_as_cc=show_as_cc, message_id=message_id, in_reply_to=in_reply_to,
send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority, communication=communication)
else:
import frappe.email
if as_markdown:
frappe.email.sendmail_md(recipients, sender=sender,
subject=subject, msg=content or message, attachments=attachments, reply_to=reply_to,
cc=cc, message_id=message_id, in_reply_to=in_reply_to, retry=retry)
else:
frappe.email.sendmail(recipients, sender=sender,
subject=subject, msg=content or message, attachments=attachments, reply_to=reply_to,
cc=cc, message_id=message_id, in_reply_to=in_reply_to, retry=retry)
if as_markdown:
from markdown2 import markdown
message = markdown(message)
if not delayed:
now = True
import email.queue
email.queue.send(recipients=recipients, sender=sender,
subject=subject, message=message,
reference_doctype = doctype or reference_doctype, reference_name = name or reference_name,
unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
attachments=attachments, reply_to=reply_to, cc=cc, message_id=message_id, in_reply_to=in_reply_to,
send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority,
communication=communication, now=now)
whitelisted = []
guest_methods = []
......@@ -847,13 +854,12 @@ def get_file_json(path):
def read_file(path, raise_not_found=False):
"""Open a file and return its content as Unicode."""
from frappe.utils import cstr
if isinstance(path, unicode):
path = path.encode("utf-8")
if os.path.exists(path):
with open(path, "r") as f:
return cstr(f.read())
return as_unicode(f.read())
elif raise_not_found:
raise IOError("{} Not Found".format(path))
else:
......
......@@ -129,6 +129,7 @@ def handle():
return build_response("json")
def validate_oauth():
from frappe.oauth import get_url_delimiter
form_dict = frappe.local.form_dict
authorization_header = frappe.get_request_header("Authorization").split(" ") if frappe.get_request_header("Authorization") else None
if authorization_header and authorization_header[0].lower() == "bearer":
......@@ -142,7 +143,7 @@ def validate_oauth():
body = r.get_data()
headers = r.headers
required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(";")
required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(get_url_delimiter())
valid, oauthlib_request = get_oauth_server().verify_request(uri, http_method, body, headers, required_scopes)
......
......@@ -9,7 +9,6 @@ import frappe
import os
import time
import redis
from functools import wraps
from frappe.utils import get_site_path
from frappe import conf
......@@ -93,7 +92,9 @@ def publish_realtime(event=None, message=None, room=None,
room = get_site_room()
if after_commit:
frappe.local.realtime_log.append([event, message, room])
params = [event, message, room]
if not params in frappe.local.realtime_log:
frappe.local.realtime_log.append(params)
else:
emit_via_redis(event, message, room)
......
- Filters Dashboard
- Dashboard with pre-defined filters in List/Report View
- Tag Category
- Show/Group tags based on category
- Updated Font Awesome version to 4.x.x
- Checkboxes in grid
- Delete selected rows
- Map selected rows from one document to another.
- Show Totals button in report
- OpenID Connect for Frappe
- Threading based on message id in Email Queue
- New control object daterangepicker for filtering
- Orientation selection in PDF
- Expand/Collapse All buttons in tree view reports
- Add attachment from email and copy attachments to Communication Record
- Bulk Upload from zip file
- Tree view decoration
- Custom menu for report view
......@@ -8,14 +8,33 @@ import frappe.model
import frappe.utils
import json, os
'''
Handle RESTful requests that are mapped to the `/api/resource` route.
Requests via FrappeClient are also handled here.
'''
@frappe.whitelist()
def get_list(doctype, fields=None, filters=None, order_by=None,
limit_start=None, limit_page_length=20):
'''Returns a list of records by filters, fields, ordering and limit
:param doctype: DocType of the data to be queried
:param fields: fields to be returned. Default is `name`
:param filters: filter list by this dict
:param order_by: Order by this fieldname
:param limit_start: Start at this index
:param limit_page_length: Number of records to be returned (default 20)'''
return frappe.get_list(doctype, fields=fields, filters=filters, order_by=order_by,
limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=False)
@frappe.whitelist()
def get(doctype, name=None, filters=None):
'''Returns a document by name or filters
:param doctype: DocType of the document to be returned
:param name: return document of this `name`
:param filters: If name is not set, filter by these values and return the first match'''
if filters and not name:
name = frappe.db.get_value(doctype, json.loads(filters))
if not name:
......@@ -29,6 +48,12 @@ def get(doctype, name=None, filters=None):
@frappe.whitelist()
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False):
'''Returns a value form a document
:param doctype: DocType to be queried
:param fieldname: Field to be returned (default `name`)
:param filters: dict or string for identifying the record'''
if not frappe.has_permission(doctype):
frappe.throw(_("Not permitted"), frappe.PermissionError)
......@@ -83,6 +108,9 @@ def set_value(doctype, name, fieldname, value=None):
@frappe.whitelist()
def insert(doc=None):
'''Insert a document
:param doc: JSON or dict object to be inserted'''
if isinstance(doc, basestring):
doc = json.loads(doc)
......@@ -98,6 +126,9 @@ def insert(doc=None):
@frappe.whitelist()
def insert_many(docs=None):
'''Insert multiple documents
:param docs: JSON or list of dict objects to be inserted in one request'''
if isinstance(docs, basestring):
docs = json.loads(docs)
......@@ -121,6 +152,9 @@ def insert_many(docs=None):
@frappe.whitelist()
def save(doc):
'''Update (save) an existing document
:param doc: JSON or dict object with the properties of the document to be updated'''
if isinstance(doc, basestring):
doc = json.loads(doc)
......@@ -129,11 +163,19 @@ def save(doc):
@frappe.whitelist()
def rename_doc(doctype, old_name, new_name, merge=False):
'''Rename document
:param doctype: DocType of the document to be renamed
:param old_name: Current `name` of the document to be renamed
:param new_name: New `name` to be set'''
new_name = frappe.rename_doc(doctype, old_name, new_name, merge=merge)
return new_name
@frappe.whitelist()
def submit(doc):
'''Submit a document
:param doc: JSON or dict object to be submitted remotely'''
if isinstance(doc, basestring):
doc = json.loads(doc)
......@@ -144,6 +186,10 @@ def submit(doc):
@frappe.whitelist()
def cancel(doctype, name):
'''Cancel a document
:param doctype: DocType of the document to be cancelled
:param name: name of the document to be cancelled'''
wrapper = frappe.get_doc(doctype, name)
wrapper.cancel()
......@@ -151,6 +197,10 @@ def cancel(doctype, name):
@frappe.whitelist()
def delete(doctype, name):
'''Delete a remote document
:param doctype: DocType of the document to be deleted
:param name: name of the document to be deleted'''
frappe.delete_doc(doctype, name)
@frappe.whitelist()
......@@ -161,6 +211,9 @@ def set_default(key, value, parent=None):
@frappe.whitelist()
def make_width_property_setter(doc):
'''Set width Property Setter
:param doc: Property Setter document with `width` property'''
if isinstance(doc, basestring):
doc = json.loads(doc)
if doc["doctype"]=="Property Setter" and doc["property"]=="width":
......@@ -168,6 +221,9 @@ def make_width_property_setter(doc):
@frappe.whitelist()
def bulk_update(docs):
'''Bulk update documents
:param docs: JSON list of documents to be updated remotely. Each document must have `docname` property'''
docs = json.loads(docs)
failed_docs = []
for doc in docs:
......@@ -187,17 +243,32 @@ def bulk_update(docs):
@frappe.whitelist()
def has_permission(doctype, docname, perm_type="read"):
'''Returns a JSON with data whether the document has the requested permission
:param doctype: DocType of the document to be checked
:param docname: `name` of the document to be checked
:param perm_type: one of `read`, `write`, `create`, `submit`, `cancel`, `report`. Default is `read`'''
# perm_type can be one of read, write, create, submit, cancel, report
return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)}
@frappe.whitelist()
def get_password(doctype, name, fieldname):
'''Return a password type property. Only applicable for System Managers
:param doctype: DocType of the document that holds the password
:param name: `name` of the document that holds the password
:param fieldname: `fieldname` of the password property
'''
frappe.only_for("System Manager")
return frappe.get_doc(doctype, name).get_password(fieldname)
@frappe.whitelist()
def get_js(items):
'''Load JS code files. Will also append translations
and extend `frappe._messages`
:param items: JSON list of paths of the js files to be loaded.'''
items = json.loads(items)
out = []
for src in items:
......
......@@ -27,7 +27,7 @@ def trigger_scheduler_event(context, event):
try:
frappe.init(site=site)
frappe.connect()
frappe.utils.scheduler.trigger(site, event, now=context.force)
frappe.utils.scheduler.trigger(site, event, now=True)
finally:
frappe.destroy()
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
docs_version = "7.x.x"
source_link = "https://github.com/frappe/frappe"
docs_base_url = "https://frappe.github.io/frappe"
......@@ -22,10 +27,13 @@ ERP for managing small and medium sized businesses.
[Get started with the Tutorial](https://frappe.github.io/frappe/user/)
"""
docs_version = "7.x.x"
google_analytics_id = 'UA-8911157-23'
def get_context(context):
context.brand_html = ('<img class="brand-logo" src="'+context.docs_base_url
+'/assets/img/frappe-bird-white.png"> Frappé Framework</img>')
context.top_bar_items = [
{"label": "Developer Tutorials", "url": context.docs_base_url + "/user", "right": 1},
{"label": "API Documentation", "url": context.docs_base_url + "/current", "right": 1}
{"label": "Tutorials", "url": context.docs_base_url + "/user", "right": 1},
{"label": "API", "url": context.docs_base_url + "/current", "right": 1},
{"label": "Forum", "url": 'https://discuss.erpnext.com', "right": 1}
]
......@@ -6,7 +6,7 @@ def get_data():
data = [
{
"label": _("Users"),
"icon": "icon-group",
"icon": "fa fa-group",
"items": [
{
"type": "doctype",
......@@ -22,41 +22,41 @@ def get_data():
},
{
"label": _("Permissions"),
"icon": "icon-lock",
"icon": "fa fa-lock",
"items": [
{
"type": "page",
"name": "permission-manager",
"label": _("Role Permissions Manager"),
"icon": "icon-lock",
"icon": "fa fa-lock",
"description": _("Set Permissions on Document Types and Roles")
},
{
"type": "page",
"name": "user-permissions",
"label": _("User Permissions Manager"),
"icon": "icon-shield",
"icon": "fa fa-shield",
"description": _("Set Permissions per User")
},
{
"type": "page",
"name": "modules_setup",
"label": _("Show / Hide Modules"),
"icon": "icon-upload",
"icon": "fa fa-upload",
"description": _("Show or hide modules globally.")
},
{
"type": "report",
"is_query_report": True,
"doctype": "User",
"icon": "icon-eye-open",
"icon": "fa fa-eye-open",
"name": "Permitted Documents For User",
"description": _("Check which Documents are readable by a User")
},
{
"type": "report",
"doctype": "DocShare",
"icon": "icon-share",
"icon": "fa fa-share",
"name": "Document Share Report",
"description": _("Report of all document shares")
}
......@@ -64,7 +64,7 @@ def get_data():
},
{
"label": _("Settings"),
"icon": "icon-wrench",
"icon": "fa fa-wrench",
"items": [
{
"type": "doctype",
......@@ -87,13 +87,13 @@ def get_data():
},
{
"label": _("Data"),
"icon": "icon-th",
"icon": "fa fa-th",
"items": [
{
"type": "page",
"name": "data-import-tool",
"label": _("Import / Export Data"),
"icon": "icon-upload",
"icon": "fa fa-upload",
"description": _("Import / Export Data from .csv files.")
},
{
......@@ -121,13 +121,13 @@ def get_data():
"name": "backups",
"label": _("Download Backups"),
"description": _("List of backups available for download"),
"icon": "icon-download"
"icon": "fa fa-download"
},
]
},
{
"label": _("Email"),
"icon": "icon-envelope",
"icon": "fa fa-envelope",
"items": [
{
"type": "doctype",
......@@ -153,7 +153,7 @@ def get_data():
},
{
"label": _("Printing"),
"icon": "icon-print",
"icon": "fa fa-print",
"items": [
{
"type": "page",
......@@ -175,7 +175,7 @@ def get_data():
},
{
"label": _("Workflow"),
"icon": "icon-random",
"icon": "fa fa-random",
"items": [
{
"type": "doctype",
......@@ -196,14 +196,14 @@ def get_data():
},
{
"label": _("Integrations"),
"icon": "icon-star",
"icon": "fa fa-star",
"items": [
{
"type": "page",
"name": "applications",
"label": _("Application Installer"),
"description": _("Install Applications."),
"icon": "icon-download"
"icon": "fa fa-download"
},
{
"type": "doctype",
......@@ -229,7 +229,7 @@ def get_data():
},
{
"label": _("Customize"),
"icon": "icon-glass",
"icon": "fa fa-glass",
"items": [
{
"type": "doctype",
......@@ -257,10 +257,16 @@ def get_data():
"type": "doctype",
"name": "DocType",
"description": _("Add custom forms.")
},
{
"type": "doctype",
"label": _("Custom Tags"),
"name": "Tag Category",
"description": _("Add your own Tag Categories")
}
]
},
]
add_setup_section(data, "frappe", "website", _("Website"), "icon-globe")
add_setup_section(data, "frappe", "website", _("Website"), "fa fa-globe")
return data
......@@ -5,7 +5,7 @@ def get_data():
return [
{
"label": _("Web Site"),
"icon": "icon-star",
"icon": "fa fa-star",
"items": [
{
"type": "doctype",
......@@ -46,7 +46,7 @@ def get_data():
},
{
"label": _("Setup"),
"icon": "icon-cog",
"icon": "fa fa-cog",
"items": [
{
"type": "doctype",
......@@ -84,5 +84,19 @@ def get_data():
"label": _("Portal Settings"),
}
]
}
},
{
"label": _("Knowledge Base"),
"items": [
{
"type": "doctype",
"name": "Help Category",
},
{
"type": "doctype",
"name": "Help Article",
},
]
},
]
......@@ -229,6 +229,7 @@ def on_doctype_update():
frappe.db.add_index("Communication", ["status", "communication_type"])
frappe.db.add_index("Communication", ["creation"])
frappe.db.add_index("Communication", ["modified"])
frappe.db.add_index("Communication", ["message_id(200)"])
def has_permission(doc, ptype, user):
if ptype=="read":
......
......@@ -10,6 +10,7 @@ from frappe.utils import (get_url, get_formatted_email, cint,
from frappe.utils.file_manager import get_file
from frappe.email.queue import check_email_limit
from frappe.utils.scheduler import log
from frappe.email.email_body import get_message_id
import frappe.email.smtp
import MySQLdb
import time
......@@ -57,11 +58,22 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
"communication_medium": communication_medium,
"sent_or_received": sent_or_received,
"reference_doctype": doctype,
"reference_name": name
"reference_name": name,
"message_id":get_message_id().strip(" <>")
})
comm.insert(ignore_permissions=True)
if not doctype:
# if no reference given, then send it against the communication
comm.db_set(dict(reference_doctype='Communication', reference_name=comm.name))
if isinstance(attachments, basestring):
attachments = json.loads(attachments)
# if not committed, delayed task doesn't find the communication
if attachments:
add_attachments(comm.name, attachments)
frappe.db.commit()
if cint(send_email):
......@@ -120,10 +132,15 @@ def _notify(doc, print_html=None, print_format=None, attachments=None,
prepare_to_notify(doc, print_html, print_format, attachments)
if doc.outgoing_email_account.send_unsubscribe_message:
unsubscribe_message = _("Leave this conversation")
else:
unsubscribe_message = ""
frappe.sendmail(
recipients=(recipients or []) + (cc or []),
show_as_cc=(cc or []),
expose_recipients=True,
recipients=(recipients or []),
cc=(cc or []),
expose_recipients="header",
sender=doc.sender,
reply_to=doc.incoming_email_account,
subject=doc.subject,
......@@ -131,8 +148,8 @@ def _notify(doc, print_html=None, print_format=None, attachments=None,
reference_doctype=doc.reference_doctype,
reference_name=doc.reference_name,
attachments=doc.attachments,
message_id=doc.name,
unsubscribe_message=_("Leave this conversation"),
message_id=doc.message_id,
unsubscribe_message=unsubscribe_message,
delayed=True,
communication=doc.name
)
......@@ -252,7 +269,7 @@ def set_incoming_outgoing_accounts(doc):
if not doc.outgoing_email_account:
doc.outgoing_email_account = frappe.db.get_value("Email Account",
{"default_outgoing": 1, "enable_outgoing": 1},
["email_id", "always_use_account_email_id_as_sender", "name"], as_dict=True) or frappe._dict()
["email_id", "always_use_account_email_id_as_sender", "name", "send_unsubscribe_message"], as_dict=True) or frappe._dict()
def get_recipients(doc, fetched_from_email_account=False):
"""Build a list of email addresses for To"""
......@@ -312,6 +329,20 @@ def get_cc(doc, recipients=None, fetched_from_email_account=False):
return cc
def add_attachments(name, attachments):
'''Add attachments to the given Communiction'''
from frappe.utils.file_manager import save_url
# loop through attachments
for a in attachments:
attach = frappe.db.get_value("File", {"name":a},
["file_name", "file_url", "is_private"], as_dict=1)
# save attachments to new doc
save_url(attach.file_url, attach.file_name, "Communication", name,
"Home/Attachments", attach.is_private)
def filter_email_list(doc, email_list, exclude, is_cc=False):
# temp variables
filtered = []
......@@ -383,6 +414,8 @@ def sendmail(communication_name, print_html=None, print_format=None, attachments
for i in xrange(3):
try:
communication = frappe.get_doc("Communication", communication_name)
if communication.sent_or_received == "Received":
communication.message_id = None
communication._notify(print_html=print_html, print_format=print_format, attachments=attachments,
recipients=recipients, cc=cc)
......
......@@ -23,6 +23,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
......@@ -48,6 +49,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Label",
"length": 0,
"no_copy": 0,
......@@ -78,6 +80,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Type",
"length": 0,
"no_copy": 0,
......@@ -106,6 +109,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Name",
"length": 0,
"no_copy": 0,
......@@ -133,6 +137,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Mandatory",
"length": 0,
"no_copy": 0,
......@@ -164,6 +169,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Precision",
"length": 0,
"no_copy": 0,
......@@ -191,6 +197,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Length",
"length": 0,
"no_copy": 0,
......@@ -217,6 +224,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Index",
"length": 0,
"no_copy": 0,
......@@ -246,6 +254,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "In List View",
"length": 0,
"no_copy": 0,
......@@ -261,6 +270,33 @@
"unique": 0,
"width": "70px"
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "in_standard_filter",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "In Standard Filter",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
......@@ -273,6 +309,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Bold",
"length": 0,
"no_copy": 0,
......@@ -300,6 +337,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Collapsible",
"length": 255,
"no_copy": 0,
......@@ -327,6 +365,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Collapsible Depends On",
"length": 0,
"no_copy": 0,
......@@ -353,6 +392,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
......@@ -378,6 +418,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Options",
"length": 0,
"no_copy": 0,
......@@ -405,6 +446,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Default",
"length": 0,
"no_copy": 0,
......@@ -432,6 +474,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Permissions",
"length": 0,
"no_copy": 0,
......@@ -457,6 +500,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Display Depends On",
"length": 255,
"no_copy": 0,
......@@ -484,6 +528,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hidden",
"length": 0,
"no_copy": 0,
......@@ -513,6 +558,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Read Only",
"length": 0,
"no_copy": 0,
......@@ -540,6 +586,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Unique",
"length": 0,
"no_copy": 0,
......@@ -567,6 +614,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Set Only Once",
"length": 0,
"no_copy": 0,
......@@ -592,6 +640,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
......@@ -617,6 +666,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Perm Level",
"length": 0,
"no_copy": 0,
......@@ -647,6 +697,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore User Permissions",
"length": 0,
"no_copy": 0,
......@@ -672,6 +723,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow on Submit",
"length": 0,
"no_copy": 0,
......@@ -701,6 +753,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Report Hide",
"length": 0,
"no_copy": 0,
......@@ -757,6 +810,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Ignore XSS Filter",
"length": 0,
"no_copy": 0,
......@@ -783,6 +837,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Display",
"length": 0,
"no_copy": 0,
......@@ -808,6 +863,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "In Filter",
"length": 0,
"no_copy": 0,
......@@ -837,6 +893,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "No Copy",
"length": 0,
"no_copy": 0,
......@@ -866,6 +923,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Hide",
"length": 0,
"no_copy": 0,
......@@ -896,6 +954,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Hide If No Value",
"length": 0,
"no_copy": 0,
......@@ -922,6 +981,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Width",
"length": 0,
"no_copy": 0,
......@@ -947,6 +1007,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Width",
"length": 0,
"no_copy": 0,
......@@ -978,6 +1039,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Columns",
"length": 0,
"no_copy": 0,
......@@ -1004,6 +1066,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
......@@ -1028,6 +1091,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
......@@ -1057,6 +1121,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"oldfieldname": "oldfieldname",
......@@ -1083,6 +1148,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"oldfieldname": "oldfieldtype",
......@@ -1118,5 +1184,5 @@
"read_only": 0,
"read_only_onload": 0,
"sort_order": "ASC",
"track_seen": 0
}
"track_seen": 0
}
\ No newline at end of file
<div class="row" style="max-height: 30px;">
<div class="col-xs-12">
<div class="text-ellipsis">
<div class="ellipsis">
{{%= list.get_avatar_and_id(doc) %}}
<!-- sample text -->
......@@ -13,7 +13,7 @@
<span style="margin-right: 8px;"
title="{{%= __("Title") %}}" class="filterable"
data-filter="check,=,Yes">
<i class="icon-icon text-muted"></i>
<i class="fa fa-icon text-muted"></i>
</span>
{{% }} %}}
......
......@@ -25,6 +25,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "",
"length": 0,
"no_copy": 0,
......@@ -33,6 +34,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -51,6 +53,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Module",
"length": 0,
"no_copy": 0,
......@@ -61,6 +64,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 1,
......@@ -80,6 +84,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Is Child Table",
"length": 0,
"no_copy": 0,
......@@ -89,6 +94,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -109,6 +115,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Editable Grid",
"length": 0,
"no_copy": 0,
......@@ -117,6 +124,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -136,6 +144,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Is Single",
"length": 0,
"no_copy": 0,
......@@ -145,6 +154,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -163,12 +173,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -180,6 +192,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"description": "",
"fieldname": "document_type",
"fieldtype": "Select",
"hidden": 0,
......@@ -187,7 +200,8 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Document Type",
"in_standard_filter": 0,
"label": "Show in Module Section",
"length": 0,
"no_copy": 0,
"oldfieldname": "document_type",
......@@ -197,35 +211,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "InnoDB",
"depends_on": "eval:!doc.issingle",
"fieldname": "engine",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Database Engine",
"length": 0,
"no_copy": 0,
"options": "InnoDB\nMyISAM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -244,6 +230,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Icon",
"length": 0,
"no_copy": 0,
......@@ -251,6 +238,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -269,6 +257,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Custom?",
"length": 0,
"no_copy": 0,
......@@ -276,6 +265,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -294,6 +284,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Beta",
"length": 0,
"no_copy": 0,
......@@ -302,6 +293,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -322,6 +314,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image View",
"length": 0,
"no_copy": 0,
......@@ -330,6 +323,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -348,6 +342,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Plugin",
"length": 0,
"no_copy": 0,
......@@ -355,6 +350,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -373,6 +369,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Fields",
"length": 0,
"no_copy": 0,
......@@ -381,6 +378,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -399,6 +397,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Fields",
"length": 0,
"no_copy": 0,
......@@ -409,6 +408,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
......@@ -427,6 +427,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Naming",
"length": 0,
"no_copy": 0,
......@@ -434,6 +435,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -453,6 +455,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Auto Name",
"length": 0,
"no_copy": 0,
......@@ -462,6 +465,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -480,6 +484,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Name Case",
"length": 0,
"no_copy": 0,
......@@ -490,6 +495,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -508,6 +514,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Description",
"length": 0,
"no_copy": 0,
......@@ -517,6 +524,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -536,12 +544,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -562,6 +572,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Title Field",
"length": 0,
"no_copy": 0,
......@@ -569,6 +580,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -588,6 +600,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Search Fields",
"length": 0,
"no_copy": 0,
......@@ -597,6 +610,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -616,6 +630,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Image Field",
"length": 0,
"no_copy": 0,
......@@ -624,6 +639,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -645,6 +661,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sort Field",
"length": 0,
"no_copy": 0,
......@@ -652,6 +669,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -672,6 +690,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Sort Order",
"length": 0,
"no_copy": 0,
......@@ -680,6 +699,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -700,6 +720,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Timeline Field",
"length": 0,
"no_copy": 0,
......@@ -708,6 +729,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -727,6 +749,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Permission Rules",
"length": 0,
"no_copy": 0,
......@@ -734,6 +757,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -753,6 +777,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Permissions",
"length": 0,
"no_copy": 0,
......@@ -763,6 +788,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -782,12 +808,14 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -806,6 +834,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Permissions Settings",
"length": 0,
"no_copy": 0,
......@@ -813,6 +842,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -831,6 +861,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "User Cannot Create",
"length": 0,
"no_copy": 0,
......@@ -840,6 +871,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -858,6 +890,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "User Cannot Search",
"length": 0,
"no_copy": 0,
......@@ -867,6 +900,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -885,6 +919,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Is Submittable",
"length": 0,
"no_copy": 0,
......@@ -892,6 +927,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -911,6 +947,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Import",
"length": 0,
"no_copy": 0,
......@@ -918,6 +955,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -936,6 +974,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Allow Rename",
"length": 0,
"no_copy": 0,
......@@ -945,6 +984,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -963,6 +1003,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "In Dialog",
"length": 0,
"no_copy": 0,
......@@ -972,6 +1013,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -990,6 +1032,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Show Print First",
"length": 0,
"no_copy": 0,
......@@ -999,6 +1042,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1017,6 +1061,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Max Attachments",
"length": 0,
"no_copy": 0,
......@@ -1026,6 +1071,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1044,6 +1090,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Other Settings",
"length": 0,
"no_copy": 0,
......@@ -1051,6 +1098,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1069,6 +1117,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hide Heading",
"length": 0,
"no_copy": 0,
......@@ -1078,6 +1127,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1096,6 +1146,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hide Toolbar",
"length": 0,
"no_copy": 0,
......@@ -1105,6 +1156,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1123,6 +1175,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Hide Copy",
"length": 0,
"no_copy": 0,
......@@ -1132,6 +1185,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1150,6 +1204,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Track Seen",
"length": 0,
"no_copy": 0,
......@@ -1158,6 +1213,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1177,6 +1233,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Quick Entry",
"length": 0,
"no_copy": 0,
......@@ -1185,6 +1242,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1203,6 +1261,7 @@
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Default Print Format",
"length": 0,
"no_copy": 0,
......@@ -1210,6 +1269,66 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "advanced",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Advanced",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
},
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "InnoDB",
"depends_on": "eval:!doc.issingle",
"fieldname": "engine",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Database Engine",
"length": 0,
"no_copy": 0,
"options": "InnoDB\nMyISAM",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
......@@ -1219,7 +1338,7 @@
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-bolt",
"icon": "fa fa-bolt",
"idx": 6,
"image_view": 0,
"in_create": 0,
......@@ -1228,7 +1347,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2016-10-13 01:13:58.133080",
"modified": "2016-11-08 01:17:33.593456",
"modified_by": "Administrator",
"module": "Core",
"name": "DocType",
......
......@@ -9,7 +9,7 @@ import frappe
from frappe import _
from frappe.utils import now, cint
from frappe.model import no_value_fields
from frappe.model import no_value_fields, default_fields
from frappe.model.document import Document
from frappe.custom.doctype.property_setter.property_setter import make_property_setter
from frappe.desk.notifications import delete_notification_count_for
......@@ -59,15 +59,47 @@ class DocType(Document):
self.make_amendable()
self.validate_website()
self.update_fields_to_fetch()
def check_developer_mode(self):
"""Throw exception if not developer mode or via patch"""
if frappe.flags.in_patch:
if frappe.flags.in_patch or frappe.flags.in_test:
return
if not frappe.conf.get("developer_mode") and not self.custom:
frappe.throw(_("Not in Developer Mode! Set in site_config.json or make 'Custom' DocType."))
def update_fields_to_fetch(self):
'''Update values for newly set fetch values'''
try:
old_meta = frappe.get_meta(frappe.get_doc('DocType', self.name), cached=False)
old_fields_to_fetch = [df.fieldname for df in old_meta.get_fields_to_fetch()]
except frappe.DoesNotExistError:
old_fields_to_fetch = []
new_meta = frappe.get_meta(self, cached=False)
if set(old_fields_to_fetch) != set([df.fieldname for df in new_meta.get_fields_to_fetch()]):
for df in new_meta.get_fields_to_fetch():
if df.fieldname not in old_fields_to_fetch:
link_fieldname, source_fieldname = df.options.split('.', 1)
link_df = new_meta.get_field(link_fieldname)
frappe.db.sql('''update
`tab{link_doctype}` source,
`tab{doctype}` target
set
target.`{fieldname}` = source.`{source_fieldname}`
where
target.`{link_fieldname}` = source.name
and ifnull(target.`{fieldname}`, '')="" '''.format(
link_doctype = link_df.options,
source_fieldname = source_fieldname,
doctype = self.name,
fieldname = df.fieldname,
link_fieldname = link_fieldname
))
def validate_document_type(self):
if self.document_type=="Transaction":
self.document_type = "Document"
......@@ -387,7 +419,6 @@ def validate_fields(meta):
if not meta.search_fields:
return
fieldname_list = [d.fieldname for d in fields]
for fieldname in (meta.search_fields or "").split(","):
fieldname = fieldname.strip()
if fieldname not in fieldname_list:
......@@ -398,8 +429,6 @@ def validate_fields(meta):
if not meta.get("title_field"):
return
fieldname_list = [d.fieldname for d in fields]
if meta.title_field not in fieldname_list:
frappe.throw(_("Title field must be a valid fieldname"), InvalidFieldNameError)
......@@ -437,8 +466,6 @@ def validate_fields(meta):
if not meta.timeline_field:
return
fieldname_list = [d.fieldname for d in fields]
if meta.timeline_field not in fieldname_list:
frappe.throw(_("Timeline field must be a valid fieldname"), InvalidFieldNameError)
......@@ -446,7 +473,22 @@ def validate_fields(meta):
if df.fieldtype not in ("Link", "Dynamic Link"):
frappe.throw(_("Timeline field must be a Link or Dynamic Link"), InvalidFieldNameError)
def check_sort_field(meta):
'''Validate that sort_field(s) is a valid field'''
if meta.sort_field:
sort_fields = [meta.sort_field]
if ',' in meta.sort_field:
sort_fields = [d.split()[0] for d in meta.sort_field.split(',')]
for fieldname in sort_fields:
if not fieldname in fieldname_list + list(default_fields):
frappe.throw(_("Sort field {0} must be a valid fieldname").format(fieldname),
InvalidFieldNameError)
fields = meta.get("fields")
fieldname_list = [d.fieldname for d in fields]
not_allowed_in_list_view = list(copy.copy(no_value_fields))
if meta.istable:
not_allowed_in_list_view.remove('Button')
......@@ -470,6 +512,7 @@ def validate_fields(meta):
check_search_fields(meta)
check_title_field(meta)
check_timeline_field(meta)
check_sort_field(meta)
def validate_permissions_for_doctype(doctype, for_remove=False):
"""Validates if permissions are set correctly."""
......
......@@ -93,7 +93,7 @@
],
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-warning-sign",
"icon": "fa fa-warning-sign",
"idx": 1,
"image_view": 0,
"in_create": 0,
......
......@@ -19,3 +19,9 @@ def set_old_logs_as_seen():
# clear old logs
frappe.db.sql("""delete from `tabError Log` where datediff(curdate(), creation) > 30""")
@frappe.whitelist()
def clear_error_logs():
'''Flush all Error Logs'''
frappe.only_for('System Manager')
frappe.db.sql('''delete from `tabError Log`''')
\ No newline at end of file
......@@ -8,4 +8,14 @@ frappe.listview_settings['Error Log'] = {
}
},
order_by: "seen asc, modified desc",
onload: function(listview) {
listview.page.add_menu_item(__("Clear Error Logs"), function() {
frappe.call({
method:'frappe.core.doctype.error_log.error_log.clear_error_logs',
callback: function() {
listview.refresh();
}
});
});
}
};
......@@ -62,7 +62,7 @@
</div>
<div class="col-lg-1">
<span class="btn btn-xs btn-default" data-toggle="collapse" data-target="#frame-{{ frameid }}-locals">
<i class="icon-list-ul"> {{ __("Locals") }}</i>
<i class="fa fa-list-ul"> {{ __("Locals") }}</i>
</span>
</div>
</div>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment