Merge remote-tracking branch 'frappe/develop' into v6-wip
Conflicts: frappe/__version__.py frappe/core/doctype/communication/communication.json frappe/hooks.py frappe/model/document.py frappe/public/css/form.css frappe/public/less/form.less requirements.txt setup.py
This commit is contained in:
commit
c9782e23e4
44 changed files with 682 additions and 343 deletions
|
|
@ -241,7 +241,7 @@ def msgprint(msg, small=0, raise_exception=0, as_table=False):
|
|||
msg = '<table border="1px" style="border-collapse: collapse" cellpadding="2px">' + ''.join(['<tr>'+''.join(['<td>%s</td>' % c for c in r])+'</tr>' for r in msg]) + '</table>'
|
||||
|
||||
if flags.print_messages:
|
||||
print "Message: " + repr(msg)
|
||||
print "Message: " + repr(msg).encode("utf-8")
|
||||
|
||||
message_log.append((small and '__small:' or '')+cstr(msg or ''))
|
||||
_raise_exception()
|
||||
|
|
@ -430,6 +430,9 @@ def has_website_permission(doctype, ptype="read", doc=None, user=None, verbose=F
|
|||
|
||||
hooks = (get_hooks("has_website_permission") or {}).get(doctype, [])
|
||||
if hooks:
|
||||
if isinstance(doc, basestring):
|
||||
doc = get_doc(doctype, doc)
|
||||
|
||||
for method in hooks:
|
||||
result = call(get_attr(method), doc=doc, ptype=ptype, user=user, verbose=verbose)
|
||||
# if even a single permission check is Falsy
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
from __future__ import unicode_literals
|
||||
__version__ = "6.0.0-wip"
|
||||
__version__ = "6.0.0"
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class HTTPRequest:
|
|||
self.domain = self.domain[4:]
|
||||
|
||||
if frappe.get_request_header('X-Forwarded-For'):
|
||||
frappe.local.request_ip = frappe.get_request_header('X-Forwarded-For')
|
||||
frappe.local.request_ip = (frappe.get_request_header('X-Forwarded-For').split(",")[0]).strip()
|
||||
|
||||
elif frappe.get_request_header('REMOTE_ADDR'):
|
||||
frappe.local.request_ip = frappe.get_request_header('REMOTE_ADDR')
|
||||
|
|
|
|||
1
frappe/change_log/v5/v5_4_0.md
Normal file
1
frappe/change_log/v5/v5_4_0.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
- Moved Backup Manager and Social Login Keys to the new **Integrations** module
|
||||
|
|
@ -72,4 +72,10 @@ def get_data():
|
|||
"type": "module",
|
||||
"system_manager": 1
|
||||
},
|
||||
"Integrations": {
|
||||
"color": "#36414C",
|
||||
"icon": "octicon octicon-plug",
|
||||
"type": "module",
|
||||
"system_manager": 1
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
frappe/config/integrations.py
Normal file
23
frappe/config/integrations.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return [
|
||||
{
|
||||
"label": _("Documents"),
|
||||
"icon": "icon-star",
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Social Login Keys",
|
||||
"description": _("Enter keys to enable login via Facebook, Google, GitHub."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Backup Manager",
|
||||
"description": _("Manage cloud backups on Dropbox"),
|
||||
"hide_count": True
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
@ -208,12 +208,6 @@ def get_data():
|
|||
"description": _("Install Applications."),
|
||||
"icon": "icon-download"
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Backup Manager",
|
||||
"description": _("Manage cloud backups on Dropbox"),
|
||||
"hide_count": True
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Scheduler Log",
|
||||
|
|
|
|||
|
|
@ -77,11 +77,6 @@ def get_data():
|
|||
"type": "doctype",
|
||||
"name": "Website Theme",
|
||||
"description": _("List of themes for Website."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Social Login Keys",
|
||||
"description": _("Enter keys to enable login via Facebook, Google, GitHub."),
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,251 +1,267 @@
|
|||
{
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-29 10:47:14",
|
||||
"description": "Keep a track of all communications",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"allow_import": 1,
|
||||
"autoname": "naming_series:",
|
||||
"creation": "2013-01-29 10:47:14",
|
||||
"description": "Keep a track of all communications",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"fields": [
|
||||
{
|
||||
"default": "COMM-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"label": "Series",
|
||||
"options": "COMM-",
|
||||
"default": "COMM-",
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"label": "Series",
|
||||
"options": "COMM-",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "sent_or_received",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Sent or Received",
|
||||
"options": "Sent\nReceived",
|
||||
"permlevel": 0,
|
||||
"fieldname": "sent_or_received",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Sent or Received",
|
||||
"options": "Sent\nReceived",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"options": "Open\nReplied\nArchived",
|
||||
"permlevel": 0,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"label": "Status",
|
||||
"options": "Open\nReplied\nArchived",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 0,
|
||||
"label": "Subject",
|
||||
"permlevel": 0,
|
||||
"description": "Integrations can use this field to set email delivery status",
|
||||
"fieldname": "delivery_status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 1,
|
||||
"label": "Delivery Status",
|
||||
"options": "\nSent\nBounced\nOpened\nMarked As Spam\nRejected\nDelayed\nSoft-Bounced\nClicked\nRecipient Unsubscribed",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 0,
|
||||
"label": "Subject",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"label": "Reference DocType",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"label": "Reference DocType",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Reference Name",
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Reference Name",
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"fieldname": "section_break_8",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "content",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Content",
|
||||
"permlevel": 0,
|
||||
"reqd": 0,
|
||||
"fieldname": "content",
|
||||
"fieldtype": "Text Editor",
|
||||
"label": "Content",
|
||||
"permlevel": 0,
|
||||
"reqd": 0,
|
||||
"width": "400"
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "additional_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Additional Info",
|
||||
"fieldname": "additional_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Additional Info",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "recipients",
|
||||
"fieldtype": "Data",
|
||||
"label": "Recipients",
|
||||
"fieldname": "recipients",
|
||||
"fieldtype": "Data",
|
||||
"label": "Recipients",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "sender",
|
||||
"fieldtype": "Data",
|
||||
"label": "Sender",
|
||||
"fieldname": "phone_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone No.",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "sender_full_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Sender Full Name",
|
||||
"permlevel": 0,
|
||||
"fieldname": "communication_medium",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Communication Medium",
|
||||
"options": "\nChat\nPhone\nEmail\nSMS\nVisit\nOther",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_14",
|
||||
"fieldtype": "Column Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "communication_medium",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Communication Medium",
|
||||
"options": "\nChat\nPhone\nEmail\nSMS\nVisit\nOther",
|
||||
"fieldname": "sender",
|
||||
"fieldtype": "Data",
|
||||
"label": "Sender",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "phone_no",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone No.",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break2",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break4",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "By",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "email_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Email Account",
|
||||
"options": "Email Account",
|
||||
"permlevel": 0,
|
||||
"fieldname": "sender_full_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Sender Full Name",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "__user",
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"fieldname": "section_break2",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "simple",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break4",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "By",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "email_account",
|
||||
"fieldtype": "Link",
|
||||
"label": "Email Account",
|
||||
"options": "Email Account",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"default": "__user",
|
||||
"fieldname": "user",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "User",
|
||||
"options": "User",
|
||||
"permlevel": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "On",
|
||||
"fieldname": "column_break5",
|
||||
"fieldtype": "Column Break",
|
||||
"label": "On",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "communication_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Date",
|
||||
"default": "Today",
|
||||
"fieldname": "communication_date",
|
||||
"fieldtype": "Datetime",
|
||||
"label": "Date",
|
||||
"permlevel": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname": "_user_tags",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "User Tags",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"fieldname": "_user_tags",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 1,
|
||||
"label": "User Tags",
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "unread_notification_sent",
|
||||
"fieldtype": "Check",
|
||||
"label": "Unread Notification Sent",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"default": "0",
|
||||
"fieldname": "unread_notification_sent",
|
||||
"fieldtype": "Check",
|
||||
"label": "Unread Notification Sent",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"icon": "icon-comment",
|
||||
"idx": 1,
|
||||
"in_dialog": 0,
|
||||
"issingle": 0,
|
||||
"modified": "2015-07-28 16:18:11.664740",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Communication",
|
||||
"owner": "Administrator",
|
||||
],
|
||||
"icon": "icon-comment",
|
||||
"idx": 1,
|
||||
"in_dialog": 0,
|
||||
"issingle": 0,
|
||||
"modified": "2015-07-28 17:18:11.664740",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "Communication",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Support Team",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Support Team",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Sales User",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"search_fields": "subject",
|
||||
],
|
||||
"search_fields": "subject",
|
||||
"title_field": "subject"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,6 +135,9 @@ class CustomizeForm(Document):
|
|||
and cint(df.get("precision")) > cint(meta_df[0].get("precision")):
|
||||
update_db = True
|
||||
|
||||
elif property == "unique":
|
||||
update_db = True
|
||||
|
||||
self.make_property_setter(property=property, value=df.get(property),
|
||||
property_type=self.docfield_properties[property], fieldname=df.fieldname)
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ def get_comments(dt, dn, limit=100):
|
|||
|
||||
communications = frappe.db.sql("""select name,
|
||||
content as comment, sender as comment_by, creation,
|
||||
communication_medium as comment_type, subject,
|
||||
communication_medium as comment_type, subject, delivery_status,
|
||||
"Communication" as doctype
|
||||
from tabCommunication
|
||||
where reference_doctype=%s and reference_name=%s
|
||||
|
|
|
|||
|
|
@ -95,8 +95,7 @@ def clear_notifications(user="*"):
|
|||
frappe.cache().delete_keys("notification_count:")
|
||||
else:
|
||||
# delete count for user
|
||||
for key in frappe.cache().get_keys("notification_count:"):
|
||||
frappe.cache().hdel(key, user)
|
||||
frappe.cache().hdel_keys("notification_count:", user)
|
||||
|
||||
def delete_notification_count_for(doctype):
|
||||
frappe.cache().delete_key("notification_count:" + doctype)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ def send(recipients=None, sender=None, subject=None, message=None, reference_doc
|
|||
if reference_doctype and reference_name:
|
||||
unsubscribed = [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
|
||||
{"reference_doctype": reference_doctype, "reference_name": reference_name})]
|
||||
|
||||
unsubscribed += [d.email for d in frappe.db.get_all("Email Unsubscribe", "email",
|
||||
{"global_unsubscribe": 1})]
|
||||
else:
|
||||
unsubscribed = []
|
||||
|
||||
|
|
@ -159,14 +162,19 @@ def unsubscribe(doctype, name, email):
|
|||
if not verify_request():
|
||||
return
|
||||
|
||||
frappe.get_doc({
|
||||
"doctype": "Email Unsubscribe",
|
||||
"email": email,
|
||||
"reference_doctype": doctype,
|
||||
"reference_name": name
|
||||
}).insert(ignore_permissions=True)
|
||||
try:
|
||||
frappe.get_doc({
|
||||
"doctype": "Email Unsubscribe",
|
||||
"email": email,
|
||||
"reference_doctype": doctype,
|
||||
"reference_name": name
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
frappe.db.commit()
|
||||
except frappe.DuplicateEntryError:
|
||||
frappe.db.rollback()
|
||||
|
||||
else:
|
||||
frappe.db.commit()
|
||||
|
||||
return_unsubscribed_page(email, doctype, name)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -43,9 +44,10 @@
|
|||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
|
|
@ -63,9 +65,30 @@
|
|||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "global_unsubscribe",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Global Unsubscribe",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
|
|
@ -75,7 +98,7 @@
|
|||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"modified": "2015-03-18 09:41:20.216319",
|
||||
"modified": "2015-08-05 06:02:12.805282",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Email",
|
||||
"name": "Email Unsubscribe",
|
||||
|
|
@ -90,6 +113,7 @@
|
|||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,32 @@ from frappe.model.document import Document
|
|||
from frappe import _
|
||||
|
||||
class EmailUnsubscribe(Document):
|
||||
def validate(self):
|
||||
if not self.global_unsubscribe and not (self.reference_doctype and self.reference_name):
|
||||
frappe.throw(_("Reference DocType and Reference Name are required"), frappe.MandatoryError)
|
||||
|
||||
if not self.global_unsubscribe and frappe.db.get_value(self.doctype, self.name, "global_unsubscribe"):
|
||||
frappe.throw(_("Delete this record to allow sending to this email address"))
|
||||
|
||||
if self.global_unsubscribe:
|
||||
if frappe.get_all("Email Unsubscribe",
|
||||
filters={"email": self.email, "global_unsubscribe": 1, "name": ["!=", self.name]}):
|
||||
frappe.throw(_("{0} already unsubscribed").format(self.email), frappe.DuplicateEntryError)
|
||||
|
||||
else:
|
||||
if frappe.get_all("Email Unsubscribe",
|
||||
filters={
|
||||
"email": self.email,
|
||||
"reference_doctype": self.reference_doctype,
|
||||
"reference_name": self.reference_name,
|
||||
"name": ["!=", self.name]
|
||||
}):
|
||||
frappe.throw(_("{0} already unsubscribed for {1} {2}").format(
|
||||
self.email, self.reference_doctype, self.reference_name),
|
||||
frappe.DuplicateEntryError)
|
||||
|
||||
def on_update(self):
|
||||
doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
doc.add_comment("Label", _("Left this conversation"), comment_by=self.email)
|
||||
if self.reference_doctype and self.reference_name:
|
||||
doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
doc.add_comment("Label", _("Left this conversation"), comment_by=self.email)
|
||||
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ class EMail:
|
|||
"Date": email.utils.formatdate(),
|
||||
"Reply-To": self.reply_to.encode("utf-8") if self.reply_to else None,
|
||||
"CC": ', '.join(self.cc).encode("utf-8") if self.cc else None,
|
||||
b'X-Frappe-Site': get_url().encode('utf-8')
|
||||
b'X-Frappe-Site': get_url().encode('utf-8'),
|
||||
}
|
||||
|
||||
# reset headers as values may be changed.
|
||||
|
|
@ -201,6 +201,10 @@ class EMail:
|
|||
del self.msg_root[key]
|
||||
self.msg_root[key] = val
|
||||
|
||||
# call hook to enable apps to modify msg_root before sending
|
||||
for hook in frappe.get_hooks("make_email_body_message"):
|
||||
frappe.get_attr(hook)(self)
|
||||
|
||||
def as_string(self):
|
||||
"""validate, build message and convert to string"""
|
||||
self.validate()
|
||||
|
|
|
|||
|
|
@ -90,11 +90,11 @@ def execute_cmd(cmd, async=False):
|
|||
if frappe.session['user'] == 'Guest':
|
||||
if (method not in frappe.guest_methods):
|
||||
frappe.msgprint(_("Not permitted"))
|
||||
raise frappe.PermissionError('Not Allowed, %s' % str(method))
|
||||
raise frappe.PermissionError('Not Allowed, {0}'.format(method))
|
||||
else:
|
||||
if not method in frappe.whitelisted:
|
||||
frappe.msgprint(_("Not permitted"))
|
||||
raise frappe.PermissionError('Not Allowed, %s' % str(method))
|
||||
raise frappe.PermissionError('Not Allowed, {0}'.format(method))
|
||||
|
||||
ret = frappe.call(method, **frappe.form_dict)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ to ERPNext.
|
|||
"""
|
||||
|
||||
app_icon = "octicon octicon-circuit-board"
|
||||
app_version = "6.0.0-wip"
|
||||
app_version = "6.0.0"
|
||||
app_color = "orange"
|
||||
github_link = "https://github.com/frappe/frappe"
|
||||
|
||||
|
|
|
|||
0
frappe/integrations/doctype/__init__.py
Normal file
0
frappe/integrations/doctype/__init__.py
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"creation": "2014-03-04 08:29:52",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "facebook",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Facebook",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "facebook_client_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Facebook Client ID",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "facebook_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Facebook Client Secret",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "google",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Google",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "google_client_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Google Client ID",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "google_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Google Client Secret",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "github",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "GitHub",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "github_client_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "GitHub Client ID",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"fieldname": "github_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "GitHub Client Secret",
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-signin",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-08-05 08:14:52.667728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Social Login Keys",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0
|
||||
}
|
||||
|
|
@ -140,6 +140,7 @@ class DbTable:
|
|||
"""
|
||||
fl = frappe.db.sql("SELECT * FROM tabDocField WHERE parent = %s", self.doctype, as_dict = 1)
|
||||
precisions = {}
|
||||
uniques = {}
|
||||
|
||||
if not frappe.flags.in_install:
|
||||
custom_fl = frappe.db.sql("""\
|
||||
|
|
@ -152,10 +153,15 @@ class DbTable:
|
|||
filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "precision"}):
|
||||
precisions[ps.field_name] = ps.value
|
||||
|
||||
# apply unique from property setters
|
||||
for ps in frappe.get_all("Property Setter", fields=["field_name", "value"],
|
||||
filters={"doc_type": self.doctype, "doctype_or_field": "DocField", "property": "unique"}):
|
||||
uniques[ps.field_name] = cint(ps.value)
|
||||
|
||||
for f in fl:
|
||||
self.columns[f['fieldname']] = DbColumn(self, f['fieldname'],
|
||||
f['fieldtype'], f.get('length'), f.get('default'), f.get('search_index'),
|
||||
f.get('options'), f.get('unique'), precisions.get(f['fieldname']) or f.get('precision'))
|
||||
f.get('options'), uniques.get(f["fieldname"], f.get('unique')), precisions.get(f['fieldname']) or f.get('precision'))
|
||||
|
||||
def get_columns_from_db(self):
|
||||
self.show_columns = frappe.db.sql("desc `%s`" % self.name)
|
||||
|
|
@ -294,18 +300,11 @@ class DbColumn:
|
|||
return
|
||||
|
||||
# type
|
||||
if (current_def['type'] != column_def) or (self.unique and not current_def['unique'] \
|
||||
and column_def not in ('text', 'longtext')):
|
||||
if (current_def['type'] != column_def) or \
|
||||
((self.unique and not current_def['unique']) and column_def not in ('text', 'longtext')):
|
||||
self.table.change_type.append(self)
|
||||
|
||||
else:
|
||||
# index
|
||||
if current_def['index'] and not self.set_index and not self.unique:
|
||||
self.table.drop_index.append(self)
|
||||
|
||||
if (not current_def['index'] and self.set_index) and not (column_def in ('text', 'longtext')):
|
||||
self.table.add_index.append(self)
|
||||
|
||||
# default
|
||||
if (self.default_changed(current_def) \
|
||||
and (self.default not in default_shortcuts) \
|
||||
|
|
@ -313,6 +312,15 @@ class DbColumn:
|
|||
and not (column_def in ['text','longtext'])):
|
||||
self.table.set_default.append(self)
|
||||
|
||||
# index should be applied or dropped irrespective of type change
|
||||
if ( (current_def['index'] and not self.set_index and not self.unique)
|
||||
or (current_def['unique'] and not self.unique) ):
|
||||
# to drop unique you have to drop index
|
||||
self.table.drop_index.append(self)
|
||||
|
||||
elif (not current_def['index'] and self.set_index) and not (column_def in ('text', 'longtext')):
|
||||
self.table.add_index.append(self)
|
||||
|
||||
def default_changed(self, current_def):
|
||||
if "decimal" in current_def['type']:
|
||||
return self.default_changed_for_decimal(current_def)
|
||||
|
|
|
|||
|
|
@ -150,27 +150,41 @@ def check_if_doc_is_linked(doc, method="Delete"):
|
|||
|
||||
if item and item.parent != doc.name and ((method=="Delete" and item.docstatus<2) or
|
||||
(method=="Cancel" and item.docstatus==1)):
|
||||
# raise exception only if
|
||||
# linked to an non-cancelled doc when deleting
|
||||
# or linked to a submitted doc when cancelling
|
||||
frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
|
||||
doc.name, item.parenttype if item.parent else link_dt, item.parent or item.name),
|
||||
frappe.LinkExistsError)
|
||||
|
||||
def check_if_doc_is_dynamically_linked(doc):
|
||||
def check_if_doc_is_dynamically_linked(doc, method="Delete"):
|
||||
for query in dynamic_link_queries:
|
||||
for df in frappe.db.sql(query, as_dict=True):
|
||||
if frappe.get_meta(df.parent).issingle:
|
||||
|
||||
# dynamic link in single doc
|
||||
refdoc = frappe.db.get_singles_dict(df.parent)
|
||||
if refdoc.get(df.options)==doc.doctype and refdoc.get(df.fieldname)==doc.name:
|
||||
if (refdoc.get(df.options)==doc.doctype
|
||||
and refdoc.get(df.fieldname)==doc.name
|
||||
and ((method=="Delete" and refdoc.docstatus < 2)
|
||||
or (method=="Cancel" and refdoc.docstatus==1))
|
||||
):
|
||||
# raise exception only if
|
||||
# linked to an non-cancelled doc when deleting
|
||||
# or linked to a submitted doc when cancelling
|
||||
frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
|
||||
doc.name, df.parent, ""), frappe.LinkExistsError)
|
||||
else:
|
||||
|
||||
# dynamic link in table
|
||||
for name in frappe.db.sql_list("""select name from `tab{parent}` where
|
||||
{options}=%s and {fieldname}=%s""".format(**df), (doc.doctype, doc.name)):
|
||||
frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}").format(doc.doctype,
|
||||
doc.name, df.parent, name), frappe.LinkExistsError)
|
||||
for refdoc in frappe.db.sql("""select name, docstatus from `tab{parent}` where
|
||||
{options}=%s and {fieldname}=%s""".format(**df), (doc.doctype, doc.name), as_dict=True):
|
||||
|
||||
if ((method=="Delete" and refdoc.docstatus < 2) or (method=="Cancel" and refdoc.docstatus==1)):
|
||||
# raise exception only if
|
||||
# linked to an non-cancelled doc when deleting
|
||||
# or linked to a submitted doc when cancelling
|
||||
frappe.throw(_("Cannot delete or cancel because {0} {1} is linked with {2} {3}")\
|
||||
.format(doc.doctype, doc.name, df.parent, refdoc.name), frappe.LinkExistsError)
|
||||
|
||||
def delete_linked_todos(doc):
|
||||
delete_doc("ToDo", frappe.db.sql_list("""select name from `tabToDo`
|
||||
|
|
|
|||
|
|
@ -457,7 +457,7 @@ class Document(BaseDocument):
|
|||
msgprint(msg)
|
||||
|
||||
if frappe.flags.print_messages:
|
||||
print self.as_dict()
|
||||
print self.as_json().encode("utf-8")
|
||||
|
||||
raise frappe.MandatoryError(", ".join((each[0] for each in missing)))
|
||||
|
||||
|
|
@ -581,7 +581,7 @@ class Document(BaseDocument):
|
|||
from frappe.model.delete_doc import check_if_doc_is_linked, check_if_doc_is_dynamically_linked
|
||||
if not self.flags.ignore_links:
|
||||
check_if_doc_is_linked(self, method="Cancel")
|
||||
check_if_doc_is_dynamically_linked(self)
|
||||
check_if_doc_is_dynamically_linked(self, method="Cancel")
|
||||
|
||||
@staticmethod
|
||||
def whitelist(f):
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ Custom
|
|||
Geo
|
||||
Desk
|
||||
Print
|
||||
Integrations
|
||||
|
|
@ -161,3 +161,15 @@ select.form-control {
|
|||
font-weight: bold;
|
||||
background-color: #fffce7;
|
||||
}
|
||||
.form-headline .alert {
|
||||
font-size: 12px;
|
||||
border-color: #d1d8dd;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
.delivery-status-indicator {
|
||||
display: inline-block;
|
||||
margin-top: -3px;
|
||||
margin-left: 1px;
|
||||
font-weight: 500;
|
||||
color: #8d99a6;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,16 @@ frappe.ui.form.ControlHTML = frappe.ui.form.Control.extend({
|
|||
},
|
||||
html: function(html) {
|
||||
this.$wrapper.html(html || this.get_content());
|
||||
},
|
||||
set_value: function(html) {
|
||||
if(html.appendTo) {
|
||||
// jquery object
|
||||
html.appendTo(this.$wrapper.empty());
|
||||
} else {
|
||||
// html
|
||||
this.df.options = html;
|
||||
this.html(html);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ frappe.ui.form.Dashboard = Class.extend({
|
|||
},
|
||||
set_headline_alert: function(text, alert_class, icon) {
|
||||
this.set_headline(repl('<div class="alert %(alert_class)s">%(icon)s%(text)s</div>', {
|
||||
"alert_class": alert_class || "alert-info",
|
||||
"alert_class": alert_class || "",
|
||||
"icon": icon ? '<i class="'+icon+'" /> ' : "",
|
||||
"text": text
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -10,15 +10,28 @@
|
|||
</span>
|
||||
</div>
|
||||
{% if(data.doctype=="Communication" || data.comment_type=="Comment") { %}
|
||||
<h6>
|
||||
<h6>
|
||||
<i class="{%= data.icon %} icon-fixed-width"></i>
|
||||
<span title="{%= data.comment_by %}">{%= data.fullname %}</span>
|
||||
<span class="text-muted" style="font-weight: normal;">
|
||||
– {%= data.comment_on %}</span>
|
||||
{% if(data.doctype=="Communication") { %}
|
||||
<span class="text-muted">–</span>
|
||||
<a href="#Form/{%= data.doctype %}/{%= data.name %}"
|
||||
class="text-muted">{%= __("Details") %}</a>
|
||||
<span class="text-muted">–</span>
|
||||
<a href="#Form/{%= data.doctype %}/{%= data.name %}"
|
||||
class="text-muted">
|
||||
{% if (data.delivery_status) {
|
||||
if (in_list(["Sent", "Opened", "Clicked"], data.delivery_status)) {
|
||||
var indicator_class = "green";
|
||||
} else {
|
||||
var indicator_class = "red";
|
||||
}
|
||||
%}
|
||||
<span class="indicator-right {%= indicator_class %} delivery-status-indicator"
|
||||
title="{%= data.delivery_status %}">
|
||||
{%= data.delivery_status %}</span>
|
||||
|
||||
{% } else { %} {%= __("Details") %} {% } %}
|
||||
</a>
|
||||
<a class="text-muted reply-link pull-right"
|
||||
data-name="{%= data.name %}">{%= __("Reply") %}</a>
|
||||
{% } %}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@ frappe.ui.form.Grid = Class.extend({
|
|||
var me = this,
|
||||
$rows = $(me.parent).find(".rows"),
|
||||
data = this.get_data();
|
||||
|
||||
if (this.frm && this.frm.docname) {
|
||||
// use doc specific docfield object
|
||||
this.df = frappe.meta.get_docfield(this.frm.doctype, this.df.fieldname, this.frm.docname);
|
||||
} else {
|
||||
// use non-doc specific docfield
|
||||
this.df = frappe.meta.get_docfield(this.df.options, this.df.fieldname);
|
||||
}
|
||||
|
||||
this.docfields = frappe.meta.get_docfields(this.doctype, this.frm.docname);
|
||||
this.display_status = frappe.perm.get_field_display_status(this.df, this.frm.doc,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
</div>
|
||||
<div class="text-right col-sm-5 col-xs-6 page-actions">
|
||||
<!-- ID and icon buttons -->
|
||||
<h6 class="text-ellipsis sub-heading rtl hide text-muted"></h6>
|
||||
<h6 class="text-ellipsis sub-heading hide text-muted"></h6>
|
||||
<span class="page-icon-group hide hidden-xs hidden-sm"></span>
|
||||
|
||||
<!-- buttons -->
|
||||
|
|
|
|||
|
|
@ -209,3 +209,18 @@ select.form-control {
|
|||
font-weight: bold;
|
||||
background-color: @light-yellow;
|
||||
}
|
||||
|
||||
.form-headline .alert {
|
||||
font-size: @text-medium;
|
||||
border-color: @border-color;
|
||||
// background-color: @light-bg;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.delivery-status-indicator {
|
||||
display: inline-block;
|
||||
margin-top: -3px;
|
||||
margin-left: 1px;
|
||||
font-weight: 500;
|
||||
color: @text-muted;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
@modal-backdrop-bg: #334143;
|
||||
@light-yellow: #fffce7;
|
||||
@text-extra-muted: @border-color;
|
||||
@text-regular: 14px;
|
||||
@text-medium: 12px;
|
||||
@text-small: 10px;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ def clear_cache(user=None):
|
|||
cache = frappe.cache()
|
||||
|
||||
groups = ("bootinfo", "user_recent", "user_roles", "user_doc", "lang",
|
||||
"defaults", "user_permissions", "roles")
|
||||
"defaults", "user_permissions", "roles", "home_page")
|
||||
|
||||
if user:
|
||||
for name in groups:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ def make_boilerplate(dest, app_name):
|
|||
with open(os.path.join(dest, hooks.app_name, hooks.app_name, "config", "desktop.py"), "w") as f:
|
||||
f.write(encode(desktop_template.format(**hooks)))
|
||||
|
||||
|
||||
print "'{app}' created at {path}".format(app=app_name, path=os.path.join(dest, app_name))
|
||||
|
||||
|
||||
manifest_template = """include MANIFEST.in
|
||||
|
|
|
|||
|
|
@ -136,8 +136,15 @@ class RedisWrapper(redis.Redis):
|
|||
except redis.exceptions.ConnectionError:
|
||||
pass
|
||||
|
||||
def hdel_keys(self, name_starts_with, key):
|
||||
"""Delete hash names with wildcard `*` and key"""
|
||||
for name in frappe.cache().get_keys(name_starts_with):
|
||||
name = name.split("|", 1)[1]
|
||||
self.hdel(name, key)
|
||||
|
||||
def hkeys(self, name):
|
||||
try:
|
||||
return super(redis.Redis, self).hkeys(self.make_key(name))
|
||||
except redis.exceptions.ConnectionError:
|
||||
return []
|
||||
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
{
|
||||
"creation": "2014-03-04 08:29:52",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "System",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "facebook",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Facebook",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "facebook_client_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Facebook Client ID",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "facebook_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"label": "Facebook Client Secret",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "google",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Google",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "google_client_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "Google Client ID",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "google_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"label": "Google Client Secret",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "github",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "GitHub",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "github_client_id",
|
||||
"fieldtype": "Data",
|
||||
"label": "GitHub Client ID",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "github_client_secret",
|
||||
"fieldtype": "Data",
|
||||
"label": "GitHub Client Secret",
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"icon": "icon-signin",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2015-02-05 05:11:46.875246",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Social Login Keys",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"permlevel": 0,
|
||||
"read": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -41,6 +41,9 @@ class WebForm(WebsiteGenerator):
|
|||
name = frappe.db.get_value(self.doc_type, {"owner": frappe.session.user}, "name")
|
||||
if name:
|
||||
frappe.form_dict.name = name
|
||||
else:
|
||||
# only a single doc allowed and no existing doc, hence new
|
||||
frappe.form_dict.new = 1
|
||||
|
||||
# always render new form if login is not required or doesn't allow editing existing ones
|
||||
if not self.login_required or not self.allow_edit:
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ def clear_cache(path=None):
|
|||
clear_sitemap()
|
||||
frappe.clear_cache("Guest")
|
||||
frappe.cache().delete_value("_website_pages")
|
||||
frappe.cache().delete_value("home_page")
|
||||
|
||||
for method in frappe.get_hooks("website_clear_cache"):
|
||||
frappe.get_attr(method)(path)
|
||||
|
|
|
|||
|
|
@ -59,8 +59,10 @@ def set_breadcrumbs(out, context):
|
|||
"""Build breadcrumbs template (deprecated)"""
|
||||
out["no_breadcrumbs"] = context.get("no_breadcrumbs", 0) or ("<!-- no-breadcrumbs -->" in out.get("content", ""))
|
||||
|
||||
# breadcrumbs
|
||||
if not out["no_breadcrumbs"] and "breadcrumbs" not in out:
|
||||
if out["no_breadcrumbs"]:
|
||||
out["breadcrumbs"] = ""
|
||||
|
||||
elif "breadcrumbs" not in out:
|
||||
out["breadcrumbs"] = frappe.get_template("templates/includes/breadcrumbs.html").render(context)
|
||||
|
||||
def set_title_and_header(out, context):
|
||||
|
|
|
|||
|
|
@ -29,3 +29,4 @@ email_reply_parser
|
|||
click
|
||||
num2words
|
||||
gevent-socketio
|
||||
watchdog==0.8.0
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -1,6 +1,6 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
version = "6.0.0-wip"
|
||||
version = "6.0.0"
|
||||
|
||||
with open("requirements.txt", "r") as f:
|
||||
install_requires = f.readlines()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue