Merge branch 'develop'
This commit is contained in:
commit
f911dbf02f
60 changed files with 2665 additions and 1677 deletions
|
|
@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json
|
|||
from .exceptions import *
|
||||
from .utils.jinja import get_jenv, get_template, render_template
|
||||
|
||||
__version__ = '8.0.7'
|
||||
__version__ = '8.0.8'
|
||||
__title__ = "Frappe Framework"
|
||||
|
||||
local = Local()
|
||||
|
|
@ -1321,3 +1321,14 @@ def get_desk_link(doctype, name):
|
|||
|
||||
def bold(text):
|
||||
return '<b>{0}</b>'.format(text)
|
||||
|
||||
def safe_eval(code, eval_globals=None, eval_locals=None):
|
||||
'''A safer `eval`'''
|
||||
if '__' in code:
|
||||
throw('Illegal rule {0}. Cannot use "__"'.format(bold(code)))
|
||||
|
||||
if not eval_globals:
|
||||
eval_globals = {}
|
||||
eval_globals['__builtins__'] = {}
|
||||
|
||||
return eval(code, eval_globals, eval_locals)
|
||||
|
|
@ -134,6 +134,12 @@ def handle_exception(e):
|
|||
# code 409 represents conflict
|
||||
http_status_code = 508
|
||||
|
||||
if http_status_code==401:
|
||||
frappe.respond_as_web_page(_("Session Expired"),
|
||||
_("Your session has expired, please login again to continue."),
|
||||
http_status_code=http_status_code, indicator_color='red')
|
||||
return_as_message = True
|
||||
|
||||
if http_status_code==403:
|
||||
frappe.respond_as_web_page(_("Not Permitted"),
|
||||
_("You do not have enough permissions to complete the action"),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,29 +12,41 @@ from frappe.utils.jinja import validate_template
|
|||
|
||||
class FeedbackTrigger(Document):
|
||||
def validate(self):
|
||||
frappe.cache().delete_value('feedback_triggers')
|
||||
validate_template(self.subject)
|
||||
validate_template(self.message)
|
||||
self.validate_condition()
|
||||
|
||||
def on_trash(self):
|
||||
frappe.cache().delete_value('feedback_triggers')
|
||||
|
||||
def validate_condition(self):
|
||||
temp_doc = frappe.new_doc(self.document_type)
|
||||
if self.condition:
|
||||
try:
|
||||
eval(self.condition, get_context(temp_doc))
|
||||
frappe.safe_eval(self.condition, None, get_context(temp_doc))
|
||||
except:
|
||||
frappe.throw(_("The condition '{0}' is invalid").format(self.condition))
|
||||
|
||||
def trigger_feedback_request(doc, method):
|
||||
""" trigger the feedback alert"""
|
||||
"""Trigger the feedback alert, or delete feedback requests on delete"""
|
||||
|
||||
if doc.flags.in_delete:
|
||||
frappe.enqueue('frappe.core.doctype.feedback_trigger.feedback_trigger.delete_feedback_request_and_feedback',
|
||||
reference_doctype=doc.doctype, reference_name=doc.name, now=frappe.flags.in_test)
|
||||
else:
|
||||
feedback_trigger = frappe.db.get_value("Feedback Trigger", { "enabled": 1, "document_type": doc.doctype })
|
||||
if feedback_trigger:
|
||||
def _get():
|
||||
triggers = {}
|
||||
for d in frappe.get_all('Feedback Trigger', dict(enabled=1), ['name', 'document_type']):
|
||||
triggers[d.document_type] = d.name
|
||||
|
||||
return triggers
|
||||
|
||||
feedback_triggers = frappe.cache().get_value('feedback_triggers', _get)
|
||||
if doc.doctype in feedback_triggers:
|
||||
if doc.flags.in_delete:
|
||||
frappe.enqueue('frappe.core.doctype.feedback_trigger.feedback_trigger.delete_feedback_request_and_feedback',
|
||||
reference_doctype=doc.doctype, reference_name=doc.name, now=frappe.flags.in_test)
|
||||
else:
|
||||
frappe.enqueue('frappe.core.doctype.feedback_trigger.feedback_trigger.send_feedback_request',
|
||||
trigger=feedback_trigger, reference_doctype=doc.doctype, reference_name=doc.name, now=frappe.flags.in_test)
|
||||
trigger=feedback_triggers[doc.doctype], reference_doctype=doc.doctype,
|
||||
reference_name=doc.name, now=frappe.flags.in_test)
|
||||
|
||||
@frappe.whitelist()
|
||||
def send_feedback_request(reference_doctype, reference_name, trigger="Manual", details=None, is_manual=False):
|
||||
|
|
@ -68,8 +80,6 @@ def send_feedback_request(reference_doctype, reference_name, trigger="Manual", d
|
|||
|
||||
@frappe.whitelist()
|
||||
def get_feedback_request_details(reference_doctype, reference_name, trigger="Manual", request=None):
|
||||
feedback_url = ""
|
||||
|
||||
if not frappe.db.get_value(reference_doctype, reference_name):
|
||||
# reference document is either deleted or renamed
|
||||
return
|
||||
|
|
@ -101,7 +111,7 @@ def get_feedback_request_details(reference_doctype, reference_name, trigger="Man
|
|||
frappe.msgprint(_("At least one reply is mandatory before requesting feedback"))
|
||||
return None
|
||||
|
||||
if recipients and eval(feedback_trigger.condition, context):
|
||||
if recipients and frappe.safe_eval(feedback_trigger.condition, None, context):
|
||||
subject = feedback_trigger.subject
|
||||
context.update({ "feedback_trigger": feedback_trigger })
|
||||
|
||||
|
|
@ -132,7 +142,7 @@ def get_feedback_request_url(reference_doctype, reference_name, recipients, trig
|
|||
"reference_doctype": reference_doctype,
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
feedback_url = "{base_url}/feedback?reference_doctype={doctype}&reference_name={docname}&email={email_id}&key={nonce}".format(
|
||||
feedback_url = "{base_url}/feedback?reference_doctype={doctype}&reference_name={docname}&email={email_id}&key={nonce}".format(
|
||||
base_url=get_url(),
|
||||
doctype=reference_doctype,
|
||||
docname=reference_name,
|
||||
|
|
@ -143,7 +153,7 @@ def get_feedback_request_url(reference_doctype, reference_name, recipients, trig
|
|||
return [ feedback_request.name, feedback_url ]
|
||||
|
||||
def is_feedback_request_already_sent(reference_doctype, reference_name, is_manual=False):
|
||||
"""
|
||||
"""
|
||||
check if feedback request mail is already sent but feedback is not submitted
|
||||
to avoid sending multiple feedback request mail
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ frappe.DataImportTool = Class.extend({
|
|||
args: {
|
||||
method: 'frappe.core.page.data_import_tool.importer.upload',
|
||||
},
|
||||
allow_multiple: 0,
|
||||
onerror: function(r) {
|
||||
me.onerror(r);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@
|
|||
"no_copy": 0,
|
||||
"oldfieldname": "fieldtype",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Attach\nAttach Image\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
|
||||
"options": "Attach\nAttach Image\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime\nSignature",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "DL.####",
|
||||
|
|
@ -22,6 +23,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Enter Form Type",
|
||||
|
|
@ -51,6 +53,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
|
|
@ -78,6 +81,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Change Label (via Custom Translation)",
|
||||
|
|
@ -106,6 +110,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Default Print Format",
|
||||
|
|
@ -135,6 +140,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Max Attachments",
|
||||
|
|
@ -162,6 +168,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Hide Copy",
|
||||
|
|
@ -189,6 +196,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Table",
|
||||
|
|
@ -218,6 +226,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Editable Grid",
|
||||
|
|
@ -247,6 +256,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Quick Entry",
|
||||
|
|
@ -264,6 +274,35 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "track_changes",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Track Changes",
|
||||
"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,
|
||||
|
|
@ -276,6 +315,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Image View",
|
||||
|
|
@ -304,6 +344,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
|
|
@ -332,6 +373,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Title Field",
|
||||
|
|
@ -361,6 +403,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Image Field",
|
||||
|
|
@ -390,6 +433,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Search Fields",
|
||||
|
|
@ -418,6 +462,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
|
|
@ -445,6 +490,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sort Field",
|
||||
|
|
@ -472,6 +518,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
|
|
@ -499,6 +546,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Sort Order",
|
||||
|
|
@ -529,6 +577,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Fields",
|
||||
|
|
@ -556,6 +605,7 @@
|
|||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Fields",
|
||||
|
|
@ -574,18 +624,18 @@
|
|||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 1,
|
||||
"icon": "fa fa-glass",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-12-29 14:40:32.113132",
|
||||
"modified": "2017-04-10 12:17:23.627634",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Custom",
|
||||
"name": "Customize Form",
|
||||
|
|
@ -601,7 +651,6 @@
|
|||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
|
|
@ -617,6 +666,7 @@
|
|||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "doc_type",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ doctype_properties = {
|
|||
'quick_entry': 'Check',
|
||||
'editable_grid': 'Check',
|
||||
'max_attachments': 'Int',
|
||||
'image_view': 'Check'
|
||||
'image_view': 'Check',
|
||||
'track_changes': 'Check',
|
||||
}
|
||||
|
||||
docfield_properties = {
|
||||
|
|
@ -63,7 +64,7 @@ docfield_properties = {
|
|||
}
|
||||
|
||||
allowed_fieldtype_change = (('Currency', 'Float', 'Percent'), ('Small Text', 'Data'),
|
||||
('Text', 'Data'), ('Text', 'Text Editor', 'Code'), ('Data', 'Select'),
|
||||
('Text', 'Data'), ('Text', 'Text Editor', 'Code', 'Signature'), ('Data', 'Select'),
|
||||
('Text', 'Small Text'))
|
||||
|
||||
class CustomizeForm(Document):
|
||||
|
|
@ -312,6 +313,7 @@ class CustomizeForm(Document):
|
|||
for allowed_changes in allowed_fieldtype_change:
|
||||
if (old_value in allowed_changes and new_value in allowed_changes):
|
||||
allowed = True
|
||||
break
|
||||
if not allowed:
|
||||
frappe.throw(_("Fieldtype cannot be changed from {0} to {1} in row {2}").format(old_value, new_value, df.idx))
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class TestCustomizeForm(unittest.TestCase):
|
|||
|
||||
d = self.get_customize_form("Event")
|
||||
self.assertEquals(d.doc_type, "Event")
|
||||
self.assertEquals(len(d.get("fields")), 27)
|
||||
self.assertEquals(len(d.get("fields")), 29)
|
||||
|
||||
d = self.get_customize_form("User")
|
||||
self.assertEquals(d.doc_type, "User")
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@
|
|||
"no_copy": 0,
|
||||
"oldfieldname": "fieldtype",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "Attach\nAttach Image\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nText\nText Editor\nTime",
|
||||
"options": "Attach\nAttach Image\nButton\nCheck\nCode\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nHeading\nHTML\nImage\nInt\nLink\nLong Text\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSignature\nSmall Text\nTable\nText\nText Editor\nTime",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
|
|
@ -1133,7 +1133,7 @@
|
|||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-27 21:43:19.748233",
|
||||
"modified": "2017-03-27 21:43:19.748243",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Custom",
|
||||
"name": "Customize Form Field",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "EV.#####",
|
||||
|
|
@ -129,6 +130,34 @@
|
|||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "repeat_this_event",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat this Event",
|
||||
"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,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
|
|
@ -272,8 +301,39 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "repeat_this_event",
|
||||
"fieldtype": "Check",
|
||||
"default": "blue",
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "red\ngreen\nblue\nyellow\nskyblue\norange",
|
||||
"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,
|
||||
"fieldname": "column_break_11",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
|
|
@ -281,10 +341,10 @@
|
|||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat this Event",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
|
|
@ -301,7 +361,7 @@
|
|||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "repeat_this_event",
|
||||
"fieldname": "section_break_11",
|
||||
"fieldname": "section_break_13",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
|
|
@ -388,7 +448,7 @@
|
|||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_11",
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
|
|
@ -795,19 +855,19 @@
|
|||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-calendar",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 1,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-22 16:25:55.420314",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2017-04-05 11:16:04.281342",
|
||||
"modified_by": "faris@erpnext.com",
|
||||
"module": "Desk",
|
||||
"name": "Event",
|
||||
"owner": "Administrator",
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ def get_events(start, end, user=None, for_reminder=False):
|
|||
if not user:
|
||||
user = frappe.session.user
|
||||
roles = frappe.get_roles(user)
|
||||
events = frappe.db.sql("""select name, subject, description,
|
||||
events = frappe.db.sql("""select name, subject, description, color,
|
||||
starts_on, ends_on, owner, all_day, event_type, repeat_this_event, repeat_on,repeat_till,
|
||||
monday, tuesday, wednesday, thursday, friday, saturday, sunday
|
||||
from tabEvent where ((
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ frappe.views.calendar["Event"] = {
|
|||
"allDay": "all_day",
|
||||
"title": "subject",
|
||||
"status": "event_type",
|
||||
"color": "color"
|
||||
},
|
||||
style_map: {
|
||||
"Public": "success",
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ def get_context(context):
|
|||
temp_doc = frappe.new_doc(self.document_type)
|
||||
if self.condition:
|
||||
try:
|
||||
eval(self.condition, get_context(temp_doc))
|
||||
frappe.safe_eval(self.condition, None, get_context(temp_doc))
|
||||
except:
|
||||
frappe.throw(_("The Condition '{0}' is invalid").format(self.condition))
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ def get_context(context):
|
|||
|
||||
doc = frappe.get_doc(self.document_type, name)
|
||||
|
||||
if self.condition and not eval(self.condition, get_context(doc)):
|
||||
if self.condition and not frappe.safe_eval(self.condition, None, get_context(doc)):
|
||||
continue
|
||||
|
||||
docs.append(doc)
|
||||
|
|
@ -95,7 +95,7 @@ def get_context(context):
|
|||
recipients = []
|
||||
for recipient in self.recipients:
|
||||
if recipient.condition:
|
||||
if not eval(recipient.condition, context):
|
||||
if not frappe.safe_eval(recipient.condition, None, context):
|
||||
continue
|
||||
if recipient.email_by_document_field:
|
||||
if validate_email_add(doc.get(recipient.email_by_document_field)):
|
||||
|
|
@ -189,16 +189,16 @@ def evaluate_alert(doc, alert, event):
|
|||
context = get_context(doc)
|
||||
|
||||
if alert.condition:
|
||||
if not eval(alert.condition, context):
|
||||
if not frappe.safe_eval(alert.condition, None, context):
|
||||
return
|
||||
|
||||
if event=="Value Change" and not doc.is_new():
|
||||
db_value = frappe.db.get_value(doc.doctype, doc.name, alert.value_changed)
|
||||
|
||||
|
||||
# cast to string if not already for comparing to doc.get's value
|
||||
if not isinstance(db_value, basestring):
|
||||
db_value = str(frappe.db.get_value(doc.doctype, doc.name, alert.value_changed))
|
||||
|
||||
|
||||
if doc.get(alert.value_changed) == db_value:
|
||||
return # value not changed
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ class ValidationError(Exception):
|
|||
class AuthenticationError(Exception):
|
||||
http_status_code = 401
|
||||
|
||||
class SessionExpired(Exception):
|
||||
http_status_code = 401
|
||||
|
||||
class PermissionError(Exception):
|
||||
http_status_code = 403
|
||||
|
||||
|
|
|
|||
|
|
@ -847,6 +847,7 @@
|
|||
"currency_fraction_units": 100,
|
||||
"currency_symbol": "\u20ac",
|
||||
"number_format": "# ###,##",
|
||||
"date_format": "dd/mm/yyyy",
|
||||
"timezones": [
|
||||
"Europe/Paris"
|
||||
]
|
||||
|
|
@ -1196,7 +1197,8 @@
|
|||
"currency_fraction": "Cent",
|
||||
"currency_fraction_units": 100,
|
||||
"currency_symbol": "\u20ac",
|
||||
"number_format": "#,###.##",
|
||||
"number_format": "#.###,##",
|
||||
"date_format": "dd/mm/yyyy",
|
||||
"timezones": [
|
||||
"Europe/Rome"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,290 +1,294 @@
|
|||
[
|
||||
{
|
||||
"code": "am",
|
||||
"code": "am",
|
||||
"name": "\u12a0\u121b\u122d\u129b"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ar",
|
||||
"code": "ar",
|
||||
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "bg",
|
||||
"code": "bg",
|
||||
"name": "b\u01celgarski"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "bn",
|
||||
"code": "bn",
|
||||
"name": "\u09ac\u09be\u0999\u09be\u09b2\u09bf"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "bo",
|
||||
"code": "bo",
|
||||
"name": "\u0f63\u0fb7\u0f0b\u0f66\u0f60\u0f72\u0f0b\u0f66\u0f90\u0f51\u0f0b"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "bs",
|
||||
"code": "bs",
|
||||
"name": "bosanski"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ca",
|
||||
"code": "ca",
|
||||
"name": "catal\u00e0"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "cs",
|
||||
"code": "cs",
|
||||
"name": "\u010desky"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "da",
|
||||
"code": "da",
|
||||
"name": "dansk"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "da-DK",
|
||||
"code": "da-DK",
|
||||
"name": "Dansk (Danmark)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "de",
|
||||
"code": "de",
|
||||
"name": "deutsch"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "el",
|
||||
"code": "el",
|
||||
"name": "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "en",
|
||||
"name": "english"
|
||||
},
|
||||
"code": "en",
|
||||
"name": "English"
|
||||
},
|
||||
{
|
||||
"code": "en-US",
|
||||
"code": "en-GB",
|
||||
"name": "English (United Kingdom)"
|
||||
},
|
||||
{
|
||||
"code": "en-US",
|
||||
"name": "English (United States)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es",
|
||||
"code": "es",
|
||||
"name": "espa\u00f1ol"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-AR",
|
||||
"code": "es-AR",
|
||||
"name": "Espa\u00f1ol (Argentina)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-CL",
|
||||
"code": "es-CL",
|
||||
"name": "Espa\u00f1ol (Chile)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-GT",
|
||||
"code": "es-GT",
|
||||
"name": "Espa\u00f1ol (Guatemala)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-MX",
|
||||
"code": "es-MX",
|
||||
"name": "Espa\u00f1ol (M\u00e9xico)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-NI",
|
||||
"code": "es-NI",
|
||||
"name": "Espa\u00f1ol (Nicaragua)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "es-PE",
|
||||
"code": "es-PE",
|
||||
"name": "Espa\u00f1ol (Per\u00fa)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "et",
|
||||
"code": "et",
|
||||
"name": "eesti"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "fa",
|
||||
"code": "fa",
|
||||
"name": "\u067e\u0627\u0631\u0633\u06cc"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "fi",
|
||||
"code": "fi",
|
||||
"name": "suomalainen"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "fr",
|
||||
"code": "fr",
|
||||
"name": "fran\u00e7ais"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "fr-CA",
|
||||
"code": "fr-CA",
|
||||
"name": "fran\u00e7ais canadien"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "gu",
|
||||
"code": "gu",
|
||||
"name": "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "he",
|
||||
"code": "he",
|
||||
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "hi",
|
||||
"code": "hi",
|
||||
"name": "\u0939\u093f\u0902\u0926\u0940"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "hr",
|
||||
"code": "hr",
|
||||
"name": "hrvatski"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "hu",
|
||||
"code": "hu",
|
||||
"name": "magyar"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "id",
|
||||
"code": "id",
|
||||
"name": "Indonesia"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "is",
|
||||
"code": "is",
|
||||
"name": "\u00edslenska"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "it",
|
||||
"code": "it",
|
||||
"name": "italiano"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ja",
|
||||
"code": "ja",
|
||||
"name": "\u65e5\u672c\u8a9e"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "km",
|
||||
"code": "km",
|
||||
"name": "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "kn",
|
||||
"code": "kn",
|
||||
"name": "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ko",
|
||||
"code": "ko",
|
||||
"name": "\ud55c\uad6d\uc758"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ku",
|
||||
"code": "ku",
|
||||
"name": "\u06a9\u0648\u0631\u062f\u06cc"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "lo",
|
||||
"code": "lo",
|
||||
"name": "\u0ea5\u0eb2\u0ea7"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "lt",
|
||||
"code": "lt",
|
||||
"name": "lietuvi\u0173 kalba"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "lv",
|
||||
"code": "lv",
|
||||
"name": "latvie\u0161u valoda"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "mk",
|
||||
"code": "mk",
|
||||
"name": "\u043c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ml",
|
||||
"code": "ml",
|
||||
"name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "mr",
|
||||
"code": "mr",
|
||||
"name": "\u092e\u0930\u093e\u0920\u0940"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ms",
|
||||
"code": "ms",
|
||||
"name": "Melayu"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "my",
|
||||
"code": "my",
|
||||
"name": "\u1019\u103c\u1014\u103a\u1019\u102c"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "nl",
|
||||
"code": "nl",
|
||||
"name": "nederlands"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "no",
|
||||
"code": "no",
|
||||
"name": "norsk"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "pl",
|
||||
"code": "pl",
|
||||
"name": "polski"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ps",
|
||||
"code": "ps",
|
||||
"name": "\u067e\u069a\u062a\u0648"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "pt",
|
||||
"code": "pt",
|
||||
"name": "portugu\u00eas"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "pt-BR",
|
||||
"code": "pt-BR",
|
||||
"name": "portugu\u00eas brasileiro"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ro",
|
||||
"code": "ro",
|
||||
"name": "rom\u00e2n"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ru",
|
||||
"code": "ru",
|
||||
"name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "rw",
|
||||
"code": "rw",
|
||||
"name": "Kinyarwanda"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "si",
|
||||
"code": "si",
|
||||
"name": "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sk",
|
||||
"code": "sk",
|
||||
"name": "sloven\u010dina (Slovak)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sl",
|
||||
"code": "sl",
|
||||
"name": "sloven\u0161\u010dina (Slovene)"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sq",
|
||||
"code": "sq",
|
||||
"name": "shqiptar"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sr",
|
||||
"code": "sr",
|
||||
"name": "\u0441\u0440\u043f\u0441\u043a\u0438"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sr-SP",
|
||||
"code": "sr-SP",
|
||||
"name": "srpski"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "sv",
|
||||
"code": "sv",
|
||||
"name": "svenska"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ta",
|
||||
"code": "ta",
|
||||
"name": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "te",
|
||||
"code": "te",
|
||||
"name": "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "th",
|
||||
"code": "th",
|
||||
"name": "\u0e44\u0e17\u0e22"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "tr",
|
||||
"code": "tr",
|
||||
"name": "T\u00fcrk"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "uk",
|
||||
"code": "uk",
|
||||
"name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "ur",
|
||||
"code": "ur",
|
||||
"name": "\u0627\u0631\u062f\u0648"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "vi",
|
||||
"code": "vi",
|
||||
"name": "vi\u1ec7t"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "zh",
|
||||
"code": "zh",
|
||||
"name": "\u7b80\u4f53\u4e2d\u6587"
|
||||
},
|
||||
},
|
||||
{
|
||||
"code": "zh-TW",
|
||||
"code": "zh-TW",
|
||||
"name": "\u7e41\u9ad4\u4e2d\u6587"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -275,8 +275,8 @@ def update_site_config(key, value, validate=True, site_config_path=None):
|
|||
value = int(value)
|
||||
|
||||
# boolean
|
||||
if value in ("false", "true"):
|
||||
value = eval(value.title())
|
||||
if value == 'false': value = False
|
||||
if value == 'true': value = True
|
||||
|
||||
# remove key if value is None
|
||||
if value == "None":
|
||||
|
|
|
|||
0
frappe/integrations/doctype/stripe_settings/__init__.py
Normal file
0
frappe/integrations/doctype/stripe_settings/__init__.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2017, Frappe Technologies and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Stripe Settings', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
120
frappe/integrations/doctype/stripe_settings/stripe_settings.json
Normal file
120
frappe/integrations/doctype/stripe_settings/stripe_settings.json
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-03-09 17:18:29.458397",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "publishable_key",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Publishable Key",
|
||||
"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": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "secret_key",
|
||||
"fieldtype": "Password",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Secret Key",
|
||||
"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": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-03-09 17:19:25.087475",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Integrations",
|
||||
"name": "Stripe Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
115
frappe/integrations/doctype/stripe_settings/stripe_settings.py
Normal file
115
frappe/integrations/doctype/stripe_settings/stripe_settings.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
from frappe import _
|
||||
import urllib
|
||||
from frappe.utils import get_url, call_hook_method, cint
|
||||
from frappe.integrations.utils import make_get_request, make_post_request, create_request_log, create_payment_gateway
|
||||
|
||||
class StripeSettings(Document):
|
||||
supported_currencies = [
|
||||
"AED", "ALL", "ANG", "ARS", "AUD", "AWG", "BBD", "BDT", "BIF", "BMD", "BND",
|
||||
"BOB", "BRL", "BSD", "BWP", "BZD", "CAD", "CHF", "CLP", "CNY", "COP", "CRC", "CVE", "CZK", "DJF",
|
||||
"DKK", "DOP", "DZD", "EGP", "ETB", "EUR", "FJD", "FKP", "GBP", "GIP", "GMD", "GNF", "GTQ", "GYD",
|
||||
"HKD", "HNL", "HRK", "HTG", "HUF", "IDR", "ILS", "INR", "ISK", "JMD", "JPY", "KES", "KHR", "KMF",
|
||||
"KRW", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "MAD", "MDL", "MNT", "MOP", "MRO", "MUR", "MVR",
|
||||
"MWK", "MXN", "MYR", "NAD", "NGN", "NIO", "NOK", "NPR", "NZD", "PAB", "PEN", "PGK", "PHP", "PKR",
|
||||
"PLN", "PYG", "QAR", "RUB", "SAR", "SBD", "SCR", "SEK", "SGD", "SHP", "SLL", "SOS", "STD", "SVC",
|
||||
"SZL", "THB", "TOP", "TTD", "TWD", "TZS", "UAH", "UGX", "USD", "UYU", "UZS", "VND", "VUV", "WST",
|
||||
"XAF", "XOF", "XPF", "YER", "ZAR"
|
||||
]
|
||||
|
||||
def validate(self):
|
||||
create_payment_gateway('Stripe')
|
||||
call_hook_method('payment_gateway_enabled', gateway='Stripe')
|
||||
if not self.flags.ignore_mandatory:
|
||||
self.validate_stripe_credentails()
|
||||
|
||||
def validate_stripe_credentails(self):
|
||||
if self.publishable_key and self.secret_key:
|
||||
header = {"Authorization": "Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))}
|
||||
try:
|
||||
make_get_request(url="https://api.stripe.com/v1/charges", headers=header)
|
||||
except Exception:
|
||||
frappe.throw(_("Seems Publishable Key or Secret Key is wrong !!!"))
|
||||
|
||||
def validate_transaction_currency(self, currency):
|
||||
if currency not in self.supported_currencies:
|
||||
frappe.throw(_("Please select another payment method. Stripe does not support transactions in currency '{0}'").format(currency))
|
||||
|
||||
def get_payment_url(self, **kwargs):
|
||||
return get_url("./integrations/stripe_checkout?{0}".format(urllib.urlencode(kwargs)))
|
||||
|
||||
def create_request(self, data):
|
||||
self.data = frappe._dict(data)
|
||||
|
||||
try:
|
||||
self.integration_request = create_request_log(self.data, "Host", "Stripe")
|
||||
return self.create_charge_on_stripe()
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
return{
|
||||
"redirect_to": frappe.redirect_to_message(_('Server Error'), _("Seems issue with server's razorpay config. Don't worry, in case of failure amount will get refunded to your account.")),
|
||||
"status": 401
|
||||
}
|
||||
|
||||
def create_charge_on_stripe(self):
|
||||
headers = {"Authorization":
|
||||
"Bearer {0}".format(self.get_password(fieldname="secret_key", raise_exception=False))}
|
||||
|
||||
data = {
|
||||
"amount": cint(self.data.amount)*100,
|
||||
"currency": self.data.currency,
|
||||
"source": self.data.stripe_token_id,
|
||||
"description": self.data.description
|
||||
}
|
||||
|
||||
redirect_to = self.data.get('redirect_to') or None
|
||||
redirect_message = self.data.get('redirect_message') or None
|
||||
|
||||
try:
|
||||
resp = make_post_request(url="https://api.stripe.com/v1/charges", headers=headers, data=data)
|
||||
|
||||
if resp.get("captured") == True:
|
||||
self.integration_request.db_set('status', 'Completed', update_modified=False)
|
||||
self.flags.status_changed_to = "Completed"
|
||||
|
||||
else:
|
||||
frappe.log_error(str(resp), 'Stripe Payment not completed')
|
||||
|
||||
except:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
# failed
|
||||
pass
|
||||
|
||||
status = frappe.flags.integration_request.status_code
|
||||
|
||||
if self.flags.status_changed_to == "Completed":
|
||||
if self.data.reference_doctype and self.data.reference_docname:
|
||||
custom_redirect_to = None
|
||||
try:
|
||||
custom_redirect_to = frappe.get_doc(self.data.reference_doctype,
|
||||
self.data.reference_docname).run_method("on_payment_authorized", self.flags.status_changed_to)
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
if custom_redirect_to:
|
||||
redirect_to = custom_redirect_to
|
||||
|
||||
redirect_url = 'payment-success'
|
||||
else:
|
||||
redirect_url = 'payment-failed'
|
||||
|
||||
if redirect_to:
|
||||
redirect_url += '?' + urllib.urlencode({'redirect_to': redirect_to})
|
||||
if redirect_message:
|
||||
redirect_url += '&' + urllib.urlencode({'redirect_message': redirect_message})
|
||||
|
||||
return {
|
||||
"redirect_to": redirect_url,
|
||||
"status": status
|
||||
}
|
||||
|
|
@ -8,15 +8,17 @@ import json, urlparse
|
|||
from frappe.utils import get_request_session
|
||||
from frappe import _
|
||||
|
||||
def make_get_request(url, auth=None, data=None):
|
||||
def make_get_request(url, auth=None, headers=None, data=None):
|
||||
if not auth:
|
||||
auth = ''
|
||||
if not data:
|
||||
data = {}
|
||||
if not headers:
|
||||
headers = {}
|
||||
|
||||
try:
|
||||
s = get_request_session()
|
||||
frappe.flags.integration_request = s.get(url, data={}, auth=auth)
|
||||
frappe.flags.integration_request = s.get(url, data={}, auth=auth, headers=headers)
|
||||
frappe.flags.integration_request.raise_for_status()
|
||||
return frappe.flags.integration_request.json()
|
||||
|
||||
|
|
@ -24,20 +26,23 @@ def make_get_request(url, auth=None, data=None):
|
|||
frappe.log_error(frappe.get_traceback())
|
||||
raise exc
|
||||
|
||||
def make_post_request(url, auth=None, data=None):
|
||||
def make_post_request(url, auth=None, headers=None, data=None):
|
||||
if not auth:
|
||||
auth = ''
|
||||
if not data:
|
||||
data = {}
|
||||
if not headers:
|
||||
headers = {}
|
||||
|
||||
try:
|
||||
s = get_request_session()
|
||||
res = s.post(url, data=data, auth=auth)
|
||||
res.raise_for_status()
|
||||
frappe.flags.integration_request = s.post(url, data=data, auth=auth, headers=headers)
|
||||
frappe.flags.integration_request.raise_for_status()
|
||||
|
||||
if res.headers.get("content-type") == "text/plain; charset=utf-8":
|
||||
return urlparse.parse_qs(res.text)
|
||||
if frappe.flags.integration_request.headers.get("content-type") == "text/plain; charset=utf-8":
|
||||
return urlparse.parse_qs(frappe.flags.integration_request.text)
|
||||
|
||||
return res.json()
|
||||
return frappe.flags.integration_request.json()
|
||||
except Exception, exc:
|
||||
frappe.log_error()
|
||||
raise exc
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ type_map = {
|
|||
,'Read Only': ('varchar', varchar_len)
|
||||
,'Attach': ('text', '')
|
||||
,'Attach Image':('text', '')
|
||||
,'Signature': ('longtext', '')
|
||||
}
|
||||
|
||||
default_columns = ['name', 'creation', 'modified', 'modified_by', 'owner',
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@
|
|||
],
|
||||
"css/frappe-rtl.css": [
|
||||
"public/css/bootstrap-rtl.css",
|
||||
"public/css/desk-rtl.css"
|
||||
"public/css/desk-rtl.css",
|
||||
"public/css/report-rtl.css"
|
||||
],
|
||||
"js/libs.min.js": [
|
||||
"public/js/lib/awesomplete/awesomplete.min.js",
|
||||
|
|
@ -68,6 +69,7 @@
|
|||
"public/js/lib/moment/moment-timezone-with-data.min.js",
|
||||
"public/js/lib/socket.io.min.js",
|
||||
"public/js/lib/markdown.js",
|
||||
"public/js/lib/jSignature.min.js",
|
||||
"public/js/frappe/translate.js",
|
||||
"public/js/lib/datepicker/datepicker.min.js",
|
||||
"public/js/lib/datepicker/locale-all.js"
|
||||
|
|
|
|||
|
|
@ -569,8 +569,19 @@ fieldset[disabled] .form-control {
|
|||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.file-upload .input-upload {
|
||||
vertical-align: top;
|
||||
}
|
||||
.file-upload .uploaded-filename {
|
||||
border: 1px solid #d1d8dd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.file-upload .uploaded-filename .btn-group {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.file-upload .uploaded-filename-display {
|
||||
max-width: 194px;
|
||||
max-width: 150px;
|
||||
}
|
||||
.frappe-rtl input,
|
||||
.frappe-rtl textarea {
|
||||
|
|
@ -668,6 +679,9 @@ fieldset[disabled] .form-control {
|
|||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
.note-editor .note-image-input {
|
||||
height: auto;
|
||||
}
|
||||
.modal .note-editor .note-btn-italic,
|
||||
.modal .note-editor .note-btn-underline,
|
||||
.modal .note-editor [data-original-title="Font Size"],
|
||||
|
|
|
|||
|
|
@ -415,6 +415,36 @@ h6.uppercase,
|
|||
border-radius: 0px;
|
||||
}
|
||||
}
|
||||
.signature-field {
|
||||
min-height: 300px;
|
||||
background: #fff;
|
||||
border: 1px solid #d1d8dd;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.signature-display {
|
||||
margin: 7px 0px;
|
||||
background: #fff;
|
||||
}
|
||||
.signature-btn-row {
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.signature-reset {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 4px 0px;
|
||||
}
|
||||
.signature-img {
|
||||
border: 1px solid #d1d8dd;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
margin-top: 5px;
|
||||
width: 100%;
|
||||
max-height: 300px;
|
||||
}
|
||||
.timeline-new-email {
|
||||
margin: 30px 0px;
|
||||
padding-left: 70px;
|
||||
|
|
@ -474,15 +504,6 @@ h6.uppercase,
|
|||
.shared-user {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.linked-with-dialog {
|
||||
width: 75%;
|
||||
}
|
||||
.linked-with-dialog .panel-body {
|
||||
padding: 0px;
|
||||
}
|
||||
.linked-with-dialog .form-section {
|
||||
padding-top: 15px;
|
||||
}
|
||||
.attach-missing-image,
|
||||
.attach-image-display {
|
||||
cursor: pointer;
|
||||
|
|
|
|||
|
|
@ -393,6 +393,10 @@
|
|||
.list-item-container:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.list-item-table {
|
||||
border: 1px solid #d1d8dd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -182,9 +182,6 @@ body {
|
|||
body[data-sidebar="0"] .navbar-home {
|
||||
margin-left: 15px !important;
|
||||
}
|
||||
.linked-with-dialog {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
@media (max-width: 991px) and (max-width: 480px) {
|
||||
#navbar-breadcrumbs li a {
|
||||
|
|
|
|||
3
frappe/public/css/report-rtl.css
Normal file
3
frappe/public/css/report-rtl.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.grid-report {
|
||||
direction: ltr;
|
||||
}
|
||||
|
|
@ -311,13 +311,61 @@ frappe.Application = Class.extend({
|
|||
method:'logout',
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
console.log(r.exc);
|
||||
return;
|
||||
}
|
||||
me.redirect_to_login();
|
||||
}
|
||||
})
|
||||
},
|
||||
handle_session_expired: function() {
|
||||
if(!frappe.app.session_expired_dialog) {
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: __('Session Expired'),
|
||||
fields: [
|
||||
{ fieldtype:'Password', fieldname:'password',
|
||||
label: __('Please Enter Your Password to Continue') },
|
||||
],
|
||||
onhide: () => {
|
||||
if (!dialog.logged_in) {
|
||||
frappe.app.redirect_to_login();
|
||||
}
|
||||
}
|
||||
});
|
||||
dialog.set_primary_action(__('Login'), () => {
|
||||
frappe.call({
|
||||
method: 'login',
|
||||
args: {
|
||||
usr: frappe.session.user,
|
||||
pwd: dialog.get_values().password
|
||||
},
|
||||
callback: (r) => {
|
||||
if (r.message==='Logged In') {
|
||||
dialog.logged_in = true;
|
||||
|
||||
// revert backdrop
|
||||
$('.modal-backdrop').css({
|
||||
'opacity': '',
|
||||
'background-color': '#334143'
|
||||
});
|
||||
}
|
||||
dialog.hide();
|
||||
},
|
||||
statusCode: () => {
|
||||
dialog.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
frappe.app.session_expired_dialog = dialog;
|
||||
}
|
||||
if(!frappe.app.session_expired_dialog.display) {
|
||||
frappe.app.session_expired_dialog.show();
|
||||
// add backdrop
|
||||
$('.modal-backdrop').css({
|
||||
'opacity': 1,
|
||||
'background-color': '#EBEFF2'
|
||||
});
|
||||
}
|
||||
},
|
||||
redirect_to_login: function() {
|
||||
window.location.href = '/';
|
||||
},
|
||||
|
|
|
|||
114
frappe/public/js/frappe/form/control.js
Normal file → Executable file
114
frappe/public/js/frappe/form/control.js
Normal file → Executable file
|
|
@ -1000,6 +1000,7 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
this.upload_options = {
|
||||
parent: this.dialog.get_field("upload_area").$wrapper,
|
||||
args: {},
|
||||
allow_multiple: 0,
|
||||
max_width: this.df.max_width,
|
||||
max_height: this.df.max_height,
|
||||
options: this.df.options,
|
||||
|
|
@ -1792,7 +1793,118 @@ frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({
|
|||
return this.grid.get_data();
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
||||
saving: false,
|
||||
loading: false,
|
||||
make: function() {
|
||||
var me = this;
|
||||
this._super();
|
||||
|
||||
// make jSignature field
|
||||
this.$pad = $('<div class="signature-field"></div>')
|
||||
.appendTo(me.wrapper)
|
||||
.jSignature({height:300, width: "100%", "lineWidth": 0.8})
|
||||
.on('change', this.on_save_sign.bind(this));
|
||||
|
||||
this.img_wrapper = $(`<div class="signature-display">
|
||||
<div class="missing-image attach-missing-image">
|
||||
<i class="octicon octicon-circle-slash"></i>
|
||||
</div></div>`)
|
||||
.appendTo(this.wrapper);
|
||||
this.img = $("<img class='img-responsive attach-image-display'>")
|
||||
.appendTo(this.img_wrapper).toggle(false);
|
||||
|
||||
|
||||
this.$btnWrapper = $(`<div class="signature-btn-row">
|
||||
<a href="#" type="button" class="signature-reset btn btn-default">
|
||||
<i class="glyphicon glyphicon-repeat"></i></a>`)
|
||||
.appendTo(this.$pad)
|
||||
.on("click", '.signature-reset', function() {
|
||||
me.on_reset_sign();
|
||||
return false;
|
||||
});
|
||||
// handle refresh by reloading the pad
|
||||
this.$wrapper.on("refresh", this.on_refresh.bind(this));
|
||||
},
|
||||
on_refresh: function(e) {
|
||||
// prevent to load the second time
|
||||
this.$wrapper.find(".control-input").toggle(false);
|
||||
this.set_editable(this.get_status()=="Write");
|
||||
this.load_pad();
|
||||
if(this.get_status()=="Read") {
|
||||
$(this.disp_area).toggle(false);
|
||||
}
|
||||
},
|
||||
set_image: function(value) {
|
||||
if(value) {
|
||||
$(this.img_wrapper).find(".missing-image").toggle(false);
|
||||
this.img.attr("src", value).toggle(true);
|
||||
} else {
|
||||
$(this.img_wrapper).find(".missing-image").toggle(true);
|
||||
this.img.toggle(false);
|
||||
}
|
||||
},
|
||||
load_pad: function() {
|
||||
// make sure not triggered during saving
|
||||
if (this.saving) return;
|
||||
// get value
|
||||
var value = this.get_value();
|
||||
// import data for pad
|
||||
if (this.$pad) {
|
||||
this.loading = true;
|
||||
// reset in all cases
|
||||
this.$pad.jSignature('reset');
|
||||
if (value) {
|
||||
// load the image to find out the size, because scaling will affect
|
||||
// stroke width
|
||||
try {
|
||||
this.$pad.jSignature('setData', value);
|
||||
this.set_image(value);
|
||||
}
|
||||
catch (e){
|
||||
console.log("Cannot set data for signature", value, e);
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
set_editable: function(editable) {
|
||||
this.$pad.toggle(editable);
|
||||
this.img_wrapper.toggle(!editable);
|
||||
this.$btnWrapper.toggle(editable);
|
||||
if (editable) {
|
||||
this.$btnWrapper.addClass('editing');
|
||||
}
|
||||
else {
|
||||
this.$btnWrapper.removeClass('editing');
|
||||
}
|
||||
},
|
||||
set_my_value: function(value) {
|
||||
if (this.saving || this.loading) return;
|
||||
this.saving = true;
|
||||
this.set_value(value);
|
||||
this.value = value;
|
||||
this.saving = false;
|
||||
},
|
||||
get_value: function() {
|
||||
return this.value? this.value: this.get_model_value();
|
||||
},
|
||||
// reset signature canvas
|
||||
on_reset_sign: function() {
|
||||
this.$pad.jSignature("reset");
|
||||
this.set_my_value("");
|
||||
},
|
||||
// save signature value to model and display
|
||||
on_save_sign: function() {
|
||||
if (this.saving || this.loading) return;
|
||||
var base64_img = this.$pad.jSignature("getData");
|
||||
this.set_my_value(base64_img);
|
||||
this.set_image(this.get_value());
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.fieldtype_icons = {
|
||||
"Date": "fa fa-calendar",
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ frappe.ui.get_upload_dialog = function(opts){
|
|||
}
|
||||
},
|
||||
callback: function(r){
|
||||
if(!r.message) return;
|
||||
dialog.$wrapper.find('[name="file_url"]').val(r.message.file_url);
|
||||
dialog.$wrapper.find('.private-file input').prop('checked', r.message.is_private);
|
||||
opts.args.filename = r.message.file_name
|
||||
|
|
|
|||
|
|
@ -3,156 +3,162 @@
|
|||
|
||||
frappe.provide("frappe.ui.form");
|
||||
|
||||
frappe.ui.form.LinkedWith = Class.extend({
|
||||
init: function(opts) {
|
||||
var me = this;
|
||||
frappe.ui.form.LinkedWith = class LinkedWith {
|
||||
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
},
|
||||
show: function() {
|
||||
}
|
||||
|
||||
show() {
|
||||
if(!this.dialog)
|
||||
this.make_dialog();
|
||||
|
||||
this.dialog.fields_dict.list.$wrapper.html('<div class="text-muted text-center" style="padding: 30px 0px">'
|
||||
+ __("Loading") + '...</div>');
|
||||
$(this.dialog.body).html(
|
||||
`<div class="text-muted text-center" style="padding: 30px 0px">
|
||||
${__("Loading")}...
|
||||
</div>`);
|
||||
|
||||
this.dialog.show();
|
||||
},
|
||||
make_dialog: function() {
|
||||
}
|
||||
|
||||
make_dialog() {
|
||||
var me = this;
|
||||
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
hide_on_page_refresh: true,
|
||||
title: __("Linked With"),
|
||||
fields: [
|
||||
{ fieldtype: "HTML", label: "list" }
|
||||
]
|
||||
title: __("Linked With")
|
||||
});
|
||||
|
||||
this.dialog.$wrapper.find(".modal-dialog").addClass("linked-with-dialog");
|
||||
|
||||
this.dialog.on_page_show = function() {
|
||||
this.dialog.on_page_show = () => {
|
||||
// execute ajax calls sequentially
|
||||
// 1. get linked doctypes
|
||||
// 2. load all doctypes
|
||||
// 3. load linked docs
|
||||
$.when(me.get_linked_doctypes())
|
||||
.then(function() { return me.load_doctypes() })
|
||||
.then(function() {
|
||||
if (me.links_not_permitted_or_missing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return me.get_linked_docs();
|
||||
});
|
||||
this.get_linked_doctypes()
|
||||
.then(() => this.load_doctypes())
|
||||
.then(() => this.links_not_permitted_or_missing())
|
||||
.then(() => this.get_linked_docs())
|
||||
.then(() => this.make_html())
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
make_html() {
|
||||
const linked_docs = this.frm.__linked_docs;
|
||||
|
||||
load_doctypes: function() {
|
||||
var me = this;
|
||||
var already_loaded = Object.keys(locals.DocType);
|
||||
var doctypes_to_load = [];
|
||||
if (me.frm.__linked_doctypes) {
|
||||
$.each(Object.keys(me.frm.__linked_doctypes), function(i, v) {
|
||||
if (already_loaded.indexOf(v)===-1) {
|
||||
doctypes_to_load.push(v);
|
||||
}
|
||||
let html;
|
||||
|
||||
if(Object.keys(linked_docs).length === 0) {
|
||||
html = __("Not Linked to any record");
|
||||
} else {
|
||||
html = Object.keys(linked_docs).map(dt => {
|
||||
return `<div class="list-item-table" style="margin-bottom: 15px">
|
||||
${this.make_doc_head(dt)}
|
||||
${linked_docs[dt]
|
||||
.map(doc => this.make_doc_row(doc, dt))
|
||||
.join("")}
|
||||
</div>`;
|
||||
});
|
||||
}
|
||||
// load all doctypes sequentially using with_doctype
|
||||
return $.when.apply($, $.map(doctypes_to_load, function(dt) {
|
||||
return frappe.model.with_doctype(dt, function() {
|
||||
if (frappe.listview_settings[dt]) {
|
||||
// add additional fields to __linked_doctypes
|
||||
me.frm.__linked_doctypes[dt].add_fields = frappe.listview_settings[dt].add_fields;
|
||||
}
|
||||
}, /*async*/ false);
|
||||
}));
|
||||
},
|
||||
|
||||
links_not_permitted_or_missing: function() {
|
||||
var me = this;
|
||||
var links = [];
|
||||
$.each(me.frm.__linked_doctypes, function(doctype, tmp) {
|
||||
if(frappe.model.can_get_report(doctype)) {
|
||||
links.push({label: __(doctype), value: doctype});
|
||||
}
|
||||
});
|
||||
$(this.dialog.body).html(html);
|
||||
}
|
||||
|
||||
links = frappe.utils.sort(links, "label");
|
||||
load_doctypes() {
|
||||
const already_loaded = Object.keys(locals.DocType);
|
||||
let doctypes_to_load = [];
|
||||
|
||||
if(!links) {
|
||||
me.dialog.fields_dict.list.$wrapper.html("<div class='alert alert-warning'>"
|
||||
+ me.frm.doctype + ": "
|
||||
+ (me.frm.__linked_doctypes ? __("Not Linked to any record.") : __("Not enough permission to see links."))
|
||||
+ "</div>")
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
get_linked_doctypes: function() {
|
||||
var me = this;
|
||||
if (this.frm.__linked_doctypes) {
|
||||
return;
|
||||
doctypes_to_load =
|
||||
Object.keys(this.frm.__linked_doctypes)
|
||||
.filter(doctype => !already_loaded.includes(doctype));
|
||||
}
|
||||
|
||||
return frappe.call({
|
||||
method: "frappe.desk.form.linked_with.get_linked_doctypes",
|
||||
args: {
|
||||
doctype: this.frm.doctype
|
||||
},
|
||||
callback: function(r) {
|
||||
me.frm.__linked_doctypes = r.message;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_linked_docs: function() {
|
||||
var me = this;
|
||||
return frappe.call({
|
||||
method:"frappe.desk.form.linked_with.get_linked_docs",
|
||||
args: {
|
||||
doctype: me.frm.doctype,
|
||||
name: me.frm.docname,
|
||||
linkinfo: me.frm.__linked_doctypes,
|
||||
for_doctype: me.for_doctype
|
||||
},
|
||||
callback: function(r) {
|
||||
var parent = me.dialog.fields_dict.list.$wrapper.empty();
|
||||
|
||||
if(keys(r.message || {}).length) {
|
||||
$.each(keys(r.message).sort(), function(i, doctype) {
|
||||
|
||||
if (Object.keys(locals.DocType).indexOf(doctype)=== -1) {
|
||||
frappe.model.with_doctype(doctype, function() {
|
||||
if (frappe.listview_settings[doctype]) {
|
||||
// add additional fields to __linked_doctypes
|
||||
me.frm.__linked_doctypes[doctype] = {}
|
||||
me.frm.__linked_doctypes[doctype].add_fields = frappe.listview_settings[doctype].add_fields;
|
||||
}
|
||||
}, /*async*/ false);
|
||||
}
|
||||
|
||||
var listview = frappe.views.get_listview(doctype, me);
|
||||
listview.no_delete = true;
|
||||
me.current_view = "List"
|
||||
|
||||
var wrapper = $('<div class="panel panel-default"><div>').appendTo(parent);
|
||||
$('<div class="panel-heading">').html(__(doctype).bold()).appendTo(wrapper);
|
||||
var body = $('<div class="panel-body">').appendTo(wrapper);
|
||||
|
||||
$.each(r.message[doctype], function(i, d) {
|
||||
d.doctype = doctype;
|
||||
listview.render($('<div class="list-row"></div>')
|
||||
.appendTo(body), d, me);
|
||||
})
|
||||
})
|
||||
} else {
|
||||
parent.html(__("Not Linked to any record."));
|
||||
// load all doctypes asynchronously using with_doctype
|
||||
const promises = doctypes_to_load.map(dt => {
|
||||
return frappe.model.with_doctype(dt, () => {
|
||||
if(frappe.listview_settings[dt]) {
|
||||
// add additional fields to __linked_doctypes
|
||||
this.frm.__linked_doctypes[dt].add_fields =
|
||||
frappe.listview_settings[dt].add_fields;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
links_not_permitted_or_missing() {
|
||||
var me = this;
|
||||
let links = null;
|
||||
|
||||
links =
|
||||
Object.keys(this.frm.__linked_doctypes)
|
||||
.filter(frappe.model.can_get_report);
|
||||
|
||||
let flag;
|
||||
if(!links) {
|
||||
$(this.dialog.body).html(
|
||||
`${this.frm.__linked_doctypes
|
||||
? __("Not enough permission to see links")
|
||||
: __("Not Linked to any record")}`);
|
||||
flag = true;
|
||||
}
|
||||
flag = false;
|
||||
|
||||
// reject Promise if not_permitted or missing
|
||||
return new Promise(
|
||||
(resolve, reject) => flag ? reject() : resolve()
|
||||
);
|
||||
}
|
||||
|
||||
get_linked_doctypes() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.frm.__linked_doctypes) {
|
||||
resolve();
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: "frappe.desk.form.linked_with.get_linked_doctypes",
|
||||
args: {
|
||||
doctype: this.frm.doctype
|
||||
},
|
||||
callback: (r) => {
|
||||
this.frm.__linked_doctypes = r.message;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get_linked_docs() {
|
||||
return frappe.call({
|
||||
method: "frappe.desk.form.linked_with.get_linked_docs",
|
||||
args: {
|
||||
doctype: this.frm.doctype,
|
||||
name: this.frm.docname,
|
||||
linkinfo: this.frm.__linked_doctypes,
|
||||
for_doctype: this.for_doctype
|
||||
},
|
||||
callback: (r) => {
|
||||
this.frm.__linked_docs = r.message || {};
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
make_doc_head(heading) {
|
||||
return `<div class="list-item list-item--head">
|
||||
<div class="list-item__content">
|
||||
${heading}
|
||||
</div></div>`;
|
||||
}
|
||||
|
||||
make_doc_row(doc, doctype) {
|
||||
return `<div class="list-item-container">
|
||||
<div class="list-item">
|
||||
<div class="list-item__content bold">
|
||||
<a href="#Form/${doctype}/${doc.name}">${doc.name}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,6 +503,8 @@ frappe.views.ListRenderer = Class.extend({
|
|||
this.render_view = function (values) {
|
||||
// prepare data before rendering view
|
||||
values = values.map(me.prepare_data.bind(this));
|
||||
// remove duplicates
|
||||
values = values.uniqBy(value => value.name);
|
||||
|
||||
if (lib_exists) {
|
||||
me.load_lib(function () {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ frappe.slickgrid_tools = {
|
|||
get_filtered_items: function(dataView) {
|
||||
var data = [];
|
||||
for (var i=0, len=dataView.getLength(); i<len; i++) {
|
||||
// remove single quotes at start and end of total labels when print/pdf
|
||||
var obj = dataView.getItem(i);
|
||||
for (var item in obj) {
|
||||
if(obj.hasOwnProperty(item) && typeof(obj[item]) == "string"
|
||||
&& obj[item].charAt(0) == "'" && obj[item].charAt(obj[item].length -1) == "'") {
|
||||
dataView.getItem(i)[item] = obj[item].substr(1, obj[item].length-2);
|
||||
}
|
||||
}
|
||||
data.push(dataView.getItem(i));
|
||||
}
|
||||
return data;
|
||||
|
|
@ -94,6 +102,16 @@ frappe.slickgrid_tools = {
|
|||
if(val===null || val===undefined) {
|
||||
val = "";
|
||||
}
|
||||
if(typeof(val) == "string") {
|
||||
// export to csv and get first or second column of the grid indented if it is. e.g: account_name
|
||||
if((i<3) && d['indent'] > 0 && (isNaN((new Date(val)).valueOf()))) {
|
||||
val = " ".repeat(d['indent'] * 8) + val;
|
||||
}
|
||||
// remove single quotes at start and end of total labels when export to csv
|
||||
if(val.charAt(0) == "'" && val.charAt(val.length -1) == "'") {
|
||||
val = val.substr(1, val.length-2);
|
||||
}
|
||||
}
|
||||
row.push(val);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -67,15 +67,22 @@ frappe.request.call = function(opts) {
|
|||
opts.success_callback && opts.success_callback(data, xhr.responseText);
|
||||
},
|
||||
401: function(xhr) {
|
||||
msgprint({message:__("You have been logged out"), indicator: 'red'});
|
||||
frappe.app.logout();
|
||||
if(frappe.app.session_expired_dialog && frappe.app.session_expired_dialog.display) {
|
||||
frappe.app.redirect_to_login();
|
||||
} else {
|
||||
frappe.app.handle_session_expired();
|
||||
};
|
||||
},
|
||||
404: function(xhr) {
|
||||
msgprint({title:__("Not found"), indicator:'red',
|
||||
message: __('The resource you are looking for is not available')});
|
||||
},
|
||||
403: function(xhr) {
|
||||
if (xhr.responseJSON && xhr.responseJSON._server_messages) {
|
||||
if (frappe.get_cookie('sid')==='Guest') {
|
||||
// session expired
|
||||
frappe.app.handle_session_expired();
|
||||
}
|
||||
else if (xhr.responseJSON && xhr.responseJSON._server_messages) {
|
||||
var _server_messages = JSON.parse(xhr.responseJSON._server_messages);
|
||||
|
||||
// avoid double messages
|
||||
|
|
@ -83,10 +90,13 @@ frappe.request.call = function(opts) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
frappe.msgprint({
|
||||
title:__("Not permitted"), indicator:'red',
|
||||
message: __('You do not have enough permissions to access this resource. Please contact your manager to get access.')});
|
||||
}
|
||||
|
||||
|
||||
frappe.utils.play_sound("error");
|
||||
msgprint({title:__("Not permitted"), indicator:'red',
|
||||
message: __('You do not have enough permissions to access this resource. Please contact your manager to get access.')});
|
||||
},
|
||||
508: function(xhr) {
|
||||
frappe.utils.play_sound("error");
|
||||
|
|
@ -233,11 +243,7 @@ frappe.request.cleanup = function(opts, r) {
|
|||
|
||||
// session expired? - Guest has no business here!
|
||||
if(r.session_expired || frappe.get_cookie("sid")==="Guest") {
|
||||
if(!frappe.app.logged_out) {
|
||||
localStorage.setItem("session_last_route", location.hash);
|
||||
msgprint(__('Session Expired. Logging you out'));
|
||||
frappe.app.logout();
|
||||
}
|
||||
frappe.app.handle_session_expired();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
|
|||
cur_dialog = null;
|
||||
}
|
||||
}
|
||||
me.onhide && me.onhide.apply(me);
|
||||
me.onhide && me.onhide();
|
||||
me.on_hide && me.on_hide();
|
||||
})
|
||||
.on("shown.bs.modal", function() {
|
||||
// focus on first input
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<div class="file-upload">
|
||||
<div class="input-upload">
|
||||
<input class="input-upload-file hidden" type="file" name="filedata" />
|
||||
<input class="input-upload-file hidden" type="file" {{ opts.allow_multiple ? "multiple" : "" }} name="filedata" />
|
||||
<button class="btn btn-primary btn-sm btn-browse">{%= __("Browse") %}</button>
|
||||
</div>
|
||||
<div class="uploaded-filename hidden" style="width: calc(100% - 80px);"></div>
|
||||
<div class="uploaded-filename hidden" style="width: 100%; margin-top: 12px;"></div>
|
||||
<div class="web-link-wrapper" style="width: calc(100% - 80px);">
|
||||
<span class="text-muted file-upload-or">{%= __("or") %}</span>
|
||||
<div class="input-link" style="width: calc(100% - 30px);">
|
||||
|
|
|
|||
|
|
@ -5,45 +5,72 @@
|
|||
frappe.upload = {
|
||||
make: function(opts) {
|
||||
if(!opts.args) opts.args = {};
|
||||
|
||||
if(opts.allow_multiple === undefined) {
|
||||
opts.allow_multiple = 1
|
||||
}
|
||||
|
||||
var d = null;
|
||||
// create new dialog if no parent given
|
||||
if(!opts.parent) {
|
||||
d = new frappe.ui.Dialog({
|
||||
title: __('Upload Attachment'),
|
||||
primary_action_label: __('Attach'),
|
||||
primary_action: function() {}
|
||||
});
|
||||
opts.parent = d.body;
|
||||
opts.btn = d.get_primary_btn();
|
||||
d.show();
|
||||
}
|
||||
|
||||
var $upload = $(frappe.render_template("upload", {opts:opts})).appendTo(opts.parent);
|
||||
var $file_input = $upload.find(".input-upload-file");
|
||||
var $uploaded_files_wrapper = $upload.find('.uploaded-filename');
|
||||
|
||||
// bind pseudo browse button
|
||||
$upload.find(".btn-browse").on("click",
|
||||
function() { $file_input.click(); });
|
||||
|
||||
$file_input.on("change", function() {
|
||||
if (this.files.length > 0) {
|
||||
if (this.files.length > 0 || opts.files) {
|
||||
var fileobjs = null;
|
||||
|
||||
if (opts.files) {
|
||||
// files added programmatically
|
||||
fileobjs = opts.files;
|
||||
delete opts.files;
|
||||
} else {
|
||||
// files from input type file
|
||||
fileobjs = $upload.find(":file").get(0).files;
|
||||
}
|
||||
var file_array = $.makeArray(fileobjs);
|
||||
|
||||
$upload.find(".web-link-wrapper").addClass("hidden");
|
||||
$upload.find(".btn-browse").removeClass("btn-primary").addClass("btn-default");
|
||||
$uploaded_files_wrapper.removeClass('hidden').empty();
|
||||
|
||||
var $uploaded_file_display = $(repl('<div class="btn-group" role="group">\
|
||||
<button type="button" class="btn btn-default btn-sm \
|
||||
ellipsis uploaded-filename-display">%(filename)s\
|
||||
</button>\
|
||||
<button type="button" class="btn btn-default btn-sm uploaded-file-remove">\
|
||||
×</button>\
|
||||
</div>', {filename: this.files[0].name}))
|
||||
.appendTo($upload.find(".uploaded-filename").removeClass("hidden").empty());
|
||||
|
||||
$uploaded_file_display.find(".uploaded-filename-display").on("click", function() {
|
||||
$file_input.click();
|
||||
});
|
||||
|
||||
$uploaded_file_display.find(".uploaded-file-remove").on("click", function() {
|
||||
$file_input.val("");
|
||||
$file_input.trigger("change");
|
||||
});
|
||||
|
||||
if(opts.on_select) {
|
||||
opts.on_select();
|
||||
}
|
||||
|
||||
if ( !("is_private" in opts) ) {
|
||||
// show Private checkbox
|
||||
$upload.find(".private-file").removeClass("hidden");
|
||||
}
|
||||
file_array = file_array.map(
|
||||
file => Object.assign(file, {is_private: 1})
|
||||
)
|
||||
$upload.data('attached_files', file_array);
|
||||
|
||||
// List of files in a grid
|
||||
$uploaded_files_wrapper.append(`
|
||||
<div class="list-item list-item--head">
|
||||
<div class="list-item__content list-item__content--flex-2">
|
||||
${__('Filename')}
|
||||
</div>
|
||||
<div class="list-item__content" style="flex: 0 0 64px">
|
||||
${__('Is Private')}
|
||||
</div>
|
||||
<div class="list-item__content list-item__content--activity" style="flex: 0 0 32px">
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
var file_pills = file_array.map(
|
||||
file => frappe.upload.make_file_row(file.name, !("is_private" in opts))
|
||||
);
|
||||
$uploaded_files_wrapper.append(file_pills);
|
||||
} else {
|
||||
$upload.find(".uploaded-filename").addClass("hidden")
|
||||
$upload.find(".web-link-wrapper").removeClass("hidden");
|
||||
|
|
@ -52,6 +79,40 @@ frappe.upload = {
|
|||
}
|
||||
});
|
||||
|
||||
if(opts.files && opts.files.length > 0) {
|
||||
$file_input.trigger('change');
|
||||
}
|
||||
|
||||
// events
|
||||
$uploaded_files_wrapper.on('click', '.list-item-container', function (e) {
|
||||
var $item = $(this);
|
||||
var filename = $item.attr('data-filename');
|
||||
var attached_files = $upload.data('attached_files');
|
||||
var $target = $(e.target);
|
||||
|
||||
if ($target.is(':checkbox')) {
|
||||
var is_private = $target.is(':checked');
|
||||
|
||||
attached_files = attached_files.map(file => {
|
||||
if (file.name === filename) {
|
||||
file.is_private = is_private ? 1 : 0;
|
||||
}
|
||||
return file;
|
||||
});
|
||||
$upload.data('attached_files', attached_files);
|
||||
}
|
||||
else if ($target.is('.uploaded-file-remove, .fa-remove')) {
|
||||
// remove file from attached_files object
|
||||
attached_files = attached_files.filter(file => file.name !== filename);
|
||||
$upload.data('attached_files', attached_files);
|
||||
|
||||
// remove row from dom
|
||||
$uploaded_files_wrapper
|
||||
.find(`.list-item-container[data-filename="${filename}"]`)
|
||||
.remove();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(!opts.btn) {
|
||||
opts.btn = $('<button class="btn btn-default btn-sm">' + __("Attach")
|
||||
|
|
@ -60,21 +121,77 @@ frappe.upload = {
|
|||
$(opts.btn).unbind("click");
|
||||
}
|
||||
|
||||
// get the first file
|
||||
// Primary button handler
|
||||
opts.btn.click(function() {
|
||||
// convert functions to values
|
||||
// close created dialog
|
||||
d && d.hide();
|
||||
|
||||
// convert functions to values
|
||||
if(opts.get_params) {
|
||||
opts.args.params = opts.get_params();
|
||||
}
|
||||
|
||||
opts.args.file_url = $upload.find('[name="file_url"]').val();
|
||||
opts.args.is_private = $upload.find('.private-file input').prop('checked') ? 1 : 0;
|
||||
// Get file url if input is visible
|
||||
var file_url = $upload.find('[name="file_url"]:visible');
|
||||
file_url = file_url.length && file_url.get(0).value;
|
||||
|
||||
var fileobj = $upload.find(":file").get(0).files[0];
|
||||
frappe.upload.upload_file(fileobj, opts.args, opts);
|
||||
if(file_url) {
|
||||
opts.args.file_url = file_url;
|
||||
frappe.upload.upload_file(null, opts.args, opts);
|
||||
} else {
|
||||
var files = $upload.data('attached_files');
|
||||
frappe.upload.upload_multiple_files(files, opts.args, opts);
|
||||
}
|
||||
});
|
||||
},
|
||||
make_file_row: function(filename, show_private) {
|
||||
var template = `
|
||||
<div class="list-item-container" data-filename="${filename}">
|
||||
<div class="list-item">
|
||||
<div class="list-item__content list-item__content--flex-2 ellipsis">
|
||||
${filename}
|
||||
</div>
|
||||
${show_private
|
||||
? `<div class="list-item__content ellipsis" style="flex: 0 0 64px;">
|
||||
<input type="checkbox" checked/>
|
||||
</div>`
|
||||
: ''}
|
||||
<div class="list-item__content list-item__content--activity ellipsis" style="flex: 0 0 32px;">
|
||||
<button class="btn btn-default btn-xs text-muted uploaded-file-remove">
|
||||
<span class="fa fa-remove"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
return $(template);
|
||||
},
|
||||
upload_multiple_files: function(files /*FileData array*/, args, opts) {
|
||||
var i = -1;
|
||||
|
||||
// upload the first file
|
||||
upload_next();
|
||||
// subsequent files will be uploaded after
|
||||
// upload_complete event is fired for the previous file
|
||||
$(document).on('upload_complete', on_upload);
|
||||
|
||||
function upload_next() {
|
||||
i += 1;
|
||||
var file = files[i];
|
||||
args.is_private = file.is_private;
|
||||
frappe.upload.upload_file(file, args, opts);
|
||||
frappe.show_progress(__('Uploading'), i+1, files.length);
|
||||
}
|
||||
|
||||
function on_upload(e, attachment) {
|
||||
if (i === files.length - 1) {
|
||||
$(document).off('upload_complete', on_upload);
|
||||
frappe.hide_progress();
|
||||
return;
|
||||
}
|
||||
upload_next();
|
||||
}
|
||||
},
|
||||
upload_file: function(fileobj, args, opts) {
|
||||
if(!fileobj && !args.file_url) {
|
||||
if(opts.on_no_attach) {
|
||||
|
|
@ -153,7 +270,7 @@ frappe.upload = {
|
|||
},
|
||||
|
||||
upload_to_server: function(fileobj, args, opts, dataurl) {
|
||||
var msgbox = msgprint(__("Uploading..."));
|
||||
// var msgbox = msgprint(__("Uploading..."));
|
||||
if(opts.start) {
|
||||
opts.start();
|
||||
}
|
||||
|
|
@ -162,11 +279,12 @@ frappe.upload = {
|
|||
args: args,
|
||||
callback: function(r) {
|
||||
if(!r._server_messages) {
|
||||
msgbox.hide();
|
||||
// msgbox.hide();
|
||||
}
|
||||
if(r.exc) {
|
||||
// if no onerror, assume callback will handle errors
|
||||
opts.onerror ? opts.onerror(r) : opts.callback(null, r);
|
||||
frappe.hide_progress();
|
||||
return;
|
||||
}
|
||||
var attachment = r.message;
|
||||
|
|
@ -177,6 +295,7 @@ frappe.upload = {
|
|||
error: function(r) {
|
||||
// if no onerror, assume callback will handle errors
|
||||
opts.onerror ? opts.onerror(r) : opts.callback(null, null, r);
|
||||
frappe.hide_progress();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -216,9 +335,9 @@ frappe.upload = {
|
|||
for (var i =0,j = fileobjs.length;i<j;i++) {
|
||||
var filename = fileobjs[i].name;
|
||||
fields.push({'fieldname': 'label1', 'fieldtype': 'Heading', 'label': filename});
|
||||
fields.push({'fieldname': 'is_private', 'fieldtype': 'Check', 'label': 'Private', 'default': 1});
|
||||
fields.push({'fieldname': filename+'_is_private', 'fieldtype': 'Check', 'label': 'Private', 'default': 1});
|
||||
}
|
||||
|
||||
|
||||
var d = new frappe.ui.Dialog({
|
||||
'title': __('Make file(s) private or public?'),
|
||||
'fields': fields,
|
||||
|
|
@ -227,11 +346,12 @@ frappe.upload = {
|
|||
d.hide();
|
||||
opts.loopcallback = function (){
|
||||
if (i < j) {
|
||||
args.is_private = d.fields_dict[fileobjs[i].name + "_is_private"].get_value()
|
||||
frappe.upload.upload_file(fileobjs[i], args, opts);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
opts.loopcallback();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ frappe.breadcrumbs = {
|
|||
label = module_info ? module_info.label : breadcrumbs.module;
|
||||
|
||||
|
||||
if(module_info && !module_info.blocked && !module_info.hidden) {
|
||||
if(module_info && !module_info.blocked) {
|
||||
$(repl('<li><a href="#modules/%(module)s">%(label)s</a></li>',
|
||||
{ module: breadcrumbs.module, label: __(label) }))
|
||||
.appendTo($breadcrumbs);
|
||||
|
|
|
|||
|
|
@ -96,31 +96,10 @@ frappe.views.Calendar = Class.extend({
|
|||
"end": "end",
|
||||
"allDay": "all_day",
|
||||
},
|
||||
styles: {
|
||||
"standard": {
|
||||
"color": "#F0F4F7"
|
||||
},
|
||||
"important": {
|
||||
"color": "#FFDCDC"
|
||||
},
|
||||
"danger": {
|
||||
"color": "#FFDCDC"
|
||||
},
|
||||
"warning": {
|
||||
"color": "#FFE6BF",
|
||||
},
|
||||
"success": {
|
||||
"color": "#E4FFC1",
|
||||
},
|
||||
"info": {
|
||||
"color": "#E8DDFF"
|
||||
},
|
||||
"inverse": {
|
||||
"color": "#D9F6FF"
|
||||
},
|
||||
"": {
|
||||
"color": "#F0F4F7"
|
||||
}
|
||||
color_map: {
|
||||
"danger": "red",
|
||||
"success": "green",
|
||||
"warning": "orange"
|
||||
},
|
||||
get_system_datetime: function(date) {
|
||||
date._offset = moment.user_utc_offset;
|
||||
|
|
@ -146,7 +125,7 @@ frappe.views.Calendar = Class.extend({
|
|||
args: me.get_args(start, end),
|
||||
callback: function(r) {
|
||||
var events = r.message;
|
||||
me.prepare_events(events);
|
||||
events = me.prepare_events(events);
|
||||
callback(events);
|
||||
}
|
||||
})
|
||||
|
|
@ -168,7 +147,6 @@ frappe.views.Calendar = Class.extend({
|
|||
if (view.name==="month" && (endDate - startDate)===86400000) {
|
||||
// detect single day click in month view
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var event = frappe.model.get_new_doc(me.doctype);
|
||||
|
|
@ -221,7 +199,8 @@ frappe.views.Calendar = Class.extend({
|
|||
},
|
||||
prepare_events: function(events) {
|
||||
var me = this;
|
||||
$.each(events || [], function(i, d) {
|
||||
|
||||
return (events || []).map(d => {
|
||||
d.id = d.name;
|
||||
d.editable = frappe.model.can_write(d.doctype || me.doctype);
|
||||
|
||||
|
|
@ -243,25 +222,21 @@ frappe.views.Calendar = Class.extend({
|
|||
|
||||
me.fix_end_date_for_event_render(d);
|
||||
|
||||
let color;
|
||||
if(me.get_css_class) {
|
||||
$.extend(d, me.styles[me.get_css_class(d)] || {});
|
||||
} else if(me.style_map) {
|
||||
$.extend(d, me.styles[me.style_map[d.status]] || {});
|
||||
color = me.color_map[me.get_css_class(d)];
|
||||
} else {
|
||||
$.extend(d, me.styles[frappe.utils.guess_style(d.status, "standard")]);
|
||||
// color field can be set in {doctype}_calendar.js
|
||||
// see event_calendar.js
|
||||
color = d.color;
|
||||
}
|
||||
d["textColor"] = "#36414C";
|
||||
})
|
||||
|
||||
var palette_colors = ['red', 'green', 'blue', 'yellow', 'skyblue', 'orange'];
|
||||
var index = 0;
|
||||
|
||||
if(events) {
|
||||
events = events.map(function(event) {
|
||||
event.className = "fc-bg-" + palette_colors[index];
|
||||
index = (index + 1) % palette_colors.length;
|
||||
})
|
||||
}
|
||||
// if invalid, fallback to blue color
|
||||
if(!Object.values(me.color_map).includes(color)) {
|
||||
color = "blue";
|
||||
}
|
||||
d.className = "fc-bg-" + color;
|
||||
return d;
|
||||
});
|
||||
},
|
||||
update_event: function(event, revertFunc) {
|
||||
var me = this;
|
||||
|
|
|
|||
|
|
@ -145,12 +145,12 @@ _f.Frm.prototype.setup_drag_drop = function() {
|
|||
throw "attach error";
|
||||
}
|
||||
|
||||
frappe.upload.multifile_upload(dataTransfer.files, me.attachments.get_args(), {
|
||||
frappe.upload.make({
|
||||
args: me.attachments.get_args(),
|
||||
files: dataTransfer.files,
|
||||
callback: function(attachment, r) {
|
||||
me.attachments.attachment_uploaded(attachment, r);
|
||||
},
|
||||
|
||||
confirm_is_private: true
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,19 @@
|
|||
}; })(jQuery);
|
||||
|
||||
;(function ($) { $.fn.datepicker.language['en'] = {
|
||||
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
||||
months: ['January','February','March','April','May','June', 'July','August','September','October','November','December'],
|
||||
monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
today: 'Today',
|
||||
clear: 'Clear',
|
||||
dateFormat: 'dd/mm/yyyy',
|
||||
timeFormat: 'hh:ii aa',
|
||||
firstDay: 0
|
||||
}; })(jQuery);
|
||||
|
||||
;(function ($) { $.fn.datepicker.language['en-GB'] = {
|
||||
days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||
daysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
daysMin: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
|
||||
|
|
@ -234,4 +247,4 @@
|
|||
dateFormat: 'yyyy-mm-dd',
|
||||
timeFormat: 'hh:ii',
|
||||
firstDay: 1
|
||||
}; })(jQuery);
|
||||
}; })(jQuery);
|
||||
|
|
|
|||
79
frappe/public/js/lib/jSignature.min.js
vendored
Executable file
79
frappe/public/js/lib/jSignature.min.js
vendored
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
|
||||
jSignature v2 "2013-12-09T05:51" "commit ID ebe94c351d7267e21b4fc741c79a8191391cb579"
|
||||
Copyright (c) 2012 Willow Systems Corp http://willow-systems.com
|
||||
Copyright (c) 2010 Brinley Ang http://www.unbolt.net
|
||||
MIT License <http://www.opensource.org/licenses/mit-license.php>
|
||||
|
||||
|
||||
base64 encoder
|
||||
MIT, GPL
|
||||
http://phpjs.org/functions/base64_encode
|
||||
+ original by: Tyler Akins (http://rumkin.com)
|
||||
+ improved by: Bayron Guevara
|
||||
+ improved by: Thunder.m
|
||||
+ improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
||||
+ bugfixed by: Pellentesque Malesuada
|
||||
+ improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
||||
+ improved by: Rafal Kukawski (http://kukawski.pl)
|
||||
|
||||
|
||||
jSignature v2 jSignature's Undo Button and undo functionality plugin
|
||||
|
||||
|
||||
jSignature v2 jSignature's custom "base30" format export and import plugins.
|
||||
|
||||
|
||||
jSignature v2 SVG export plugin.
|
||||
|
||||
|
||||
Simplify.js BSD
|
||||
(c) 2012, Vladimir Agafonkin
|
||||
mourner.github.com/simplify-js
|
||||
|
||||
*/
|
||||
(function(){function r(c){var a,b=c.css("color"),d;c=c[0];for(var l=!1;c&&!d&&!l;){try{a=$(c).css("background-color")}catch(E){a="transparent"}"transparent"!==a&&"rgba(0, 0, 0, 0)"!==a&&(d=a);l=c.body;c=c.parentNode}c=/rgb[a]*\((\d+),\s*(\d+),\s*(\d+)/;var l=/#([AaBbCcDdEeFf\d]{2})([AaBbCcDdEeFf\d]{2})([AaBbCcDdEeFf\d]{2})/,h;a=void 0;(a=b.match(c))?h={r:parseInt(a[1],10),g:parseInt(a[2],10),b:parseInt(a[3],10)}:(a=b.match(l))&&(h={r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)});var e;
|
||||
d?(a=void 0,(a=d.match(c))?e={r:parseInt(a[1],10),g:parseInt(a[2],10),b:parseInt(a[3],10)}:(a=d.match(l))&&(e={r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)})):e=h?127<Math.max.apply(null,[h.r,h.g,h.b])?{r:0,g:0,b:0}:{r:255,g:255,b:255}:{r:255,g:255,b:255};a=function(a){return"rgb("+[a.r,a.g,a.b].join(", ")+")"};h&&e?(c=Math.max.apply(null,[h.r,h.g,h.b]),h=Math.max.apply(null,[e.r,e.g,e.b]),h=Math.round(h+-0.75*(h-c)),h={r:h,g:h,b:h}):h?(h=Math.max.apply(null,[h.r,h.g,h.b]),c=1,127<
|
||||
h&&(c=-1),h=Math.round(h+96*c),h={r:h,g:h,b:h}):h={r:191,g:191,b:191};return{color:b,"background-color":e?a(e):d,"decor-color":a(h)}}function k(c,a){this.x=c;this.y=a;this.reverse=function(){return new this.constructor(-1*this.x,-1*this.y)};this._length=null;this.getLength=function(){this._length||(this._length=Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2)));return this._length};var b=function(a){return Math.round(a/Math.abs(a))};this.resizeTo=function(a){if(0===this.x&&0===this.y)this._length=
|
||||
0;else if(0===this.x)this._length=a,this.y=a*b(this.y);else if(0===this.y)this._length=a,this.x=a*b(this.x);else{var c=Math.abs(this.y/this.x),e=Math.sqrt(Math.pow(a,2)/(1+Math.pow(c,2))),c=c*e;this._length=a;this.x=e*b(this.x);this.y=c*b(this.y)}return this};this.angleTo=function(a){var b=this.getLength()*a.getLength();return 0===b?0:Math.acos(Math.min(Math.max((this.x*a.x+this.y*a.y)/b,-1),1))/Math.PI}}function g(c,a){this.x=c;this.y=a;this.getVectorToCoordinates=function(a,c){return new k(a-this.x,
|
||||
c-this.y)};this.getVectorFromCoordinates=function(a,c){return this.getVectorToCoordinates(a,c).reverse()};this.getVectorToPoint=function(a){return new k(a.x-this.x,a.y-this.y)};this.getVectorFromPoint=function(a){return this.getVectorToPoint(a).reverse()}}function n(c,a,b,d,l){this.data=c;this.context=a;if(c.length)for(var e=c.length,h,m,A=0;A<e;A++){h=c[A];m=h.x.length;b.call(a,h);for(var f=1;f<m;f++)d.call(a,h,f);l.call(a,h)}this.changed=function(){};this.startStrokeFn=b;this.addToStrokeFn=d;this.endStrokeFn=
|
||||
l;this.inStroke=!1;this._stroke=this._lastPoint=null;this.startStroke=function(a){if(a&&"number"==typeof a.x&&"number"==typeof a.y){this._stroke={x:[a.x],y:[a.y]};this.data.push(this._stroke);this._lastPoint=a;this.inStroke=!0;var b=this._stroke,c=this.startStrokeFn,d=this.context;setTimeout(function(){c.call(d,b)},3);return a}return null};this.addToStroke=function(a){if(this.inStroke&&"number"===typeof a.x&&"number"===typeof a.y&&4<Math.abs(a.x-this._lastPoint.x)+Math.abs(a.y-this._lastPoint.y)){var b=
|
||||
this._stroke.x.length;this._stroke.x.push(a.x);this._stroke.y.push(a.y);this._lastPoint=a;var c=this._stroke,d=this.addToStrokeFn,l=this.context;setTimeout(function(){d.call(l,c,b)},3);return a}return null};this.endStroke=function(){var a=this.inStroke;this.inStroke=!1;this._lastPoint=null;if(a){var b=this._stroke,c=this.endStrokeFn,d=this.context,l=this.changed;setTimeout(function(){c.call(d,b);l.call(d)},3);return!0}return null}}function s(c,a,b,d){if("ratio"===a||"%"===a.split("")[a.length-1])this.eventTokens[b+
|
||||
".parentresized"]=d.subscribe(b+".parentresized",function(a,e,h,m){return function(){var m=e.width();if(m!==h){for(var f in a)a.hasOwnProperty(f)&&(d.unsubscribe(a[f]),delete a[f]);var p=c.settings;c.$parent.children().remove();for(f in c)c.hasOwnProperty(f)&&delete c[f];f=p.data;var m=1*m/h,x=[],D,q,g,k,s,n;q=0;for(g=f.length;q<g;q++){n=f[q];D={x:[],y:[]};k=0;for(s=n.x.length;k<s;k++)D.x.push(n.x[k]*m),D.y.push(n.y[k]*m);x.push(D)}p.data=x;e[b](p)}}}(this.eventTokens,this.$parent,this.$parent.width(),
|
||||
1*this.canvas.width/this.canvas.height))}function v(c,a,b){var d=this.$parent=$(c);c=this.eventTokens={};this.events=new t(this);var l=$.fn[f]("globalEvents"),e={width:"ratio",height:"ratio",sizeRatio:4,color:"#000","background-color":"#fff","decor-color":"#eee",lineWidth:0,minFatFingerCompensation:-10,showUndoButton:!1,readOnly:!1,data:[]};$.extend(e,r(d));a&&$.extend(e,a);this.settings=e;for(var h in b)b.hasOwnProperty(h)&&b[h].call(this,h);this.events.publish(f+".initializing");this.$controlbarUpper=
|
||||
$('<div style="padding:0 !important; margin:0 !important;width: 100% !important; height: 0 !important; -ms-touch-action: none;margin-top:-1em !important; margin-bottom:1em !important;"></div>').appendTo(d);this.isCanvasEmulator=!1;a=this.canvas=this.initializeCanvas(e);b=$(a);this.$controlbarLower=$('<div style="padding:0 !important; margin:0 !important;width: 100% !important; height: 0 !important; -ms-touch-action: none;margin-top:-1.5em !important; margin-bottom:1.5em !important; position: relative;"></div>').appendTo(d);
|
||||
this.canvasContext=a.getContext("2d");b.data(f+".this",this);e.lineWidth=function(a,b){return a?a:Math.max(Math.round(b/400),2)}(e.lineWidth,a.width);this.lineCurveThreshold=3*e.lineWidth;e.cssclass&&""!=$.trim(e.cssclass)&&b.addClass(e.cssclass);this.fatFingerCompensation=0;d=function(a){var b,c,d=function(d){d=d.changedTouches&&0<d.changedTouches.length?d.changedTouches[0]:d;return new g(Math.round(d.pageX+b),Math.round(d.pageY+c)+a.fatFingerCompensation)},e=new u(750,function(){a.dataEngine.endStroke()});
|
||||
this.drawEndHandler=function(b){if(!a.settings.readOnly){try{b.preventDefault()}catch(c){}e.clear();a.dataEngine.endStroke()}};this.drawStartHandler=function(l){if(!a.settings.readOnly){l.preventDefault();var h=$(a.canvas).offset();b=-1*h.left;c=-1*h.top;a.dataEngine.startStroke(d(l));e.kick()}};this.drawMoveHandler=function(b){a.settings.readOnly||(b.preventDefault(),a.dataEngine.inStroke&&(a.dataEngine.addToStroke(d(b)),e.kick()))};return this}.call({},this);(function(a,b,c){var d=this.canvas,l=
|
||||
$(d);this.isCanvasEmulator?(l.bind("mousemove."+f,c),l.bind("mouseup."+f,a),l.bind("mousedown."+f,b)):(d.ontouchstart=function(l){d.onmousedown=d.onmouseup=d.onmousemove=void 0;this.fatFingerCompensation=e.minFatFingerCompensation&&-3*e.lineWidth>e.minFatFingerCompensation?-3*e.lineWidth:e.minFatFingerCompensation;b(l);d.ontouchend=a;d.ontouchstart=b;d.ontouchmove=c},d.onmousedown=function(e){d.ontouchstart=d.ontouchend=d.ontouchmove=void 0;b(e);d.onmousedown=b;d.onmouseup=a;d.onmousemove=c},window.navigator.msPointerEnabled&&
|
||||
(d.onmspointerdown=b,d.onmspointerup=a,d.onmspointermove=c))}).call(this,d.drawEndHandler,d.drawStartHandler,d.drawMoveHandler);c[f+".windowmouseup"]=l.subscribe(f+".windowmouseup",d.drawEndHandler);this.events.publish(f+".attachingEventHandlers");s.call(this,this,e.width.toString(10),f,l);this.resetCanvas(e.data);this.events.publish(f+".initialized");return this}function w(c){if(c.getContext)return!1;var a=c.ownerDocument.parentWindow,b=a.FlashCanvas?c.ownerDocument.parentWindow.FlashCanvas:"undefined"===
|
||||
typeof FlashCanvas?void 0:FlashCanvas;if(b){c=b.initElement(c);b=1;a&&a.screen&&a.screen.deviceXDPI&&a.screen.logicalXDPI&&(b=1*a.screen.deviceXDPI/a.screen.logicalXDPI);if(1!==b)try{$(c).children("object").get(0).resize(Math.ceil(c.width*b),Math.ceil(c.height*b)),c.getContext("2d").scale(b,b)}catch(d){}return!0}throw Error("Canvas element does not support 2d context. jSignature cannot proceed.");}var f="jSignature",u=function(c,a){var b;this.kick=function(){clearTimeout(b);b=setTimeout(a,c)};this.clear=
|
||||
function(){clearTimeout(b)};return this},t=function(c){this.topics={};this.context=c?c:this;this.publish=function(a,b,c,e){if(this.topics[a]){var f=this.topics[a],h=Array.prototype.slice.call(arguments,1),m=[],q,g,p,x;g=0;for(p=f.length;g<p;g++)x=f[g],q=x[0],x[1]&&(x[0]=function(){},m.push(g)),q.apply(this.context,h);g=0;for(p=m.length;g<p;g++)f.splice(m[g],1)}};this.subscribe=function(a,b,c){this.topics[a]?this.topics[a].push([b,c]):this.topics[a]=[[b,c]];return{topic:a,callback:b}};this.unsubscribe=
|
||||
function(a){if(this.topics[a.topic])for(var b=this.topics[a.topic],c=0,e=b.length;c<e;c++)b[c]&&b[c][0]===a.callback&&b.splice(c,1)}},y=function(c,a,b,d,e){c.beginPath();c.moveTo(a,b);c.lineTo(d,e);c.closePath();c.stroke()},C=function(c){var a=this.canvasContext,b=c.x[0];c=c.y[0];var d=this.settings.lineWidth,e=a.fillStyle;a.fillStyle=a.strokeStyle;a.fillRect(b+d/-2,c+d/-2,d,d);a.fillStyle=e},q=function(c,a){var b=new g(c.x[a-1],c.y[a-1]),d=new g(c.x[a],c.y[a]),e=b.getVectorToPoint(d);if(1<a){var f=
|
||||
new g(c.x[a-2],c.y[a-2]),h=f.getVectorToPoint(b),m;if(h.getLength()>this.lineCurveThreshold){m=2<a?(new g(c.x[a-3],c.y[a-3])).getVectorToPoint(f):new k(0,0);var q=0.35*h.getLength(),n=h.angleTo(m.reverse()),p=e.angleTo(h.reverse());m=(new k(m.x+h.x,m.y+h.y)).resizeTo(Math.max(0.05,n)*q);var x=(new k(h.x+e.x,h.y+e.y)).reverse().resizeTo(Math.max(0.05,p)*q),h=this.canvasContext,q=f.x,p=f.y,n=b.x,D=b.y,s=f.x+m.x,f=f.y+m.y;m=b.x+x.x;x=b.y+x.y;h.beginPath();h.moveTo(q,p);h.bezierCurveTo(s,f,m,x,n,D);h.closePath();
|
||||
h.stroke()}}e.getLength()<=this.lineCurveThreshold&&y(this.canvasContext,b.x,b.y,d.x,d.y)},e=function(c){var a=c.x.length-1;if(0<a){var b=new g(c.x[a],c.y[a]),d=new g(c.x[a-1],c.y[a-1]),e=d.getVectorToPoint(b);if(e.getLength()>this.lineCurveThreshold)if(1<a){c=(new g(c.x[a-2],c.y[a-2])).getVectorToPoint(d);var f=(new k(c.x+e.x,c.y+e.y)).resizeTo(e.getLength()/2),e=this.canvasContext;c=d.x;var a=d.y,h=b.x,m=b.y,q=d.x+f.x,d=d.y+f.y,f=b.x,b=b.y;e.beginPath();e.moveTo(c,a);e.bezierCurveTo(q,d,f,b,h,m);
|
||||
e.closePath();e.stroke()}else y(this.canvasContext,d.x,d.y,b.x,b.y)}};v.prototype.resetCanvas=function(c,a){var b=this.canvas,d=this.settings,l=this.canvasContext,g=this.isCanvasEmulator,h=b.width,m=b.height;a||l.clearRect(0,0,h+30,m+30);l.shadowColor=l.fillStyle=d["background-color"];g&&l.fillRect(0,0,h+30,m+30);l.lineWidth=Math.ceil(parseInt(d.lineWidth,10));l.lineCap=l.lineJoin="round";if(null!=d["decor-color"]){l.strokeStyle=d["decor-color"];l.shadowOffsetX=0;l.shadowOffsetY=0;var A=Math.round(m/
|
||||
5);y(l,1.5*A,m-A,h-1.5*A,m-A)}l.strokeStyle=d.color;g||(l.shadowColor=l.strokeStyle,l.shadowOffsetX=0.5*l.lineWidth,l.shadowOffsetY=-0.6*l.lineWidth,l.shadowBlur=0);c||(c=[]);l=this.dataEngine=new n(c,this,C,q,e);d.data=c;$(b).data(f+".data",c).data(f+".settings",d);l.changed=function(a,b,c){return function(){b.publish(c+".change");a.trigger("change")}}(this.$parent,this.events,f);l.changed();return!0};v.prototype.initializeCanvas=function(c){var a=document.createElement("canvas"),b=$(a);c.width===
|
||||
c.height&&"ratio"===c.height&&(c.width="100%");b.css("margin",0).css("padding",0).css("border","none").css("height","ratio"!==c.height&&c.height?c.height.toString(10):1).css("width","ratio"!==c.width&&c.width?c.width.toString(10):1).css("-ms-touch-action","none");b.appendTo(this.$parent);"ratio"===c.height?b.css("height",Math.round(b.width()/c.sizeRatio)):"ratio"===c.width&&b.css("width",Math.round(b.height()*c.sizeRatio));b.addClass(f);a.width=b.width();a.height=b.height();this.isCanvasEmulator=
|
||||
w(a);a.onselectstart=function(a){a&&a.preventDefault&&a.preventDefault();a&&a.stopPropagation&&a.stopPropagation();return!1};return a};(function(c){function a(a,b,c){var d=new Image,e=this;d.onload=function(){e.getContext("2d").drawImage(d,0,0,d.width<e.width?d.width:e.width,d.height<e.height?d.height:e.height)};d.src="data:"+b+","+a}function b(a,b){this.find("canvas."+f).add(this.filter("canvas."+f)).data(f+".this").resetCanvas(a,b);return this}function d(a,b){if(void 0===b&&"string"===typeof a&&
|
||||
"data:"===a.substr(0,5)&&(b=a.slice(5).split(",")[0],a=a.slice(6+b.length),b===a))return;var c=this.find("canvas."+f).add(this.filter("canvas."+f));if(m.hasOwnProperty(b))0!==c.length&&m[b].call(c[0],a,b,function(a){return function(){return a.resetCanvas.apply(a,arguments)}}(c.data(f+".this")));else throw Error(f+" is unable to find import plugin with for format '"+String(b)+"'");return this}var e=new t;(function(a,b,c,d){var e,h=function(){a.publish(b+".parentresized")};c(d).bind("resize."+b,function(){e&&
|
||||
clearTimeout(e);e=setTimeout(h,500)}).bind("mouseup."+b,function(c){a.publish(b+".windowmouseup")})})(e,f,$,c);var q={},h={"default":function(a){return this.toDataURL()},"native":function(a){return a},image:function(a){a=this.toDataURL();if("string"===typeof a&&4<a.length&&"data:"===a.slice(0,5)&&-1!==a.indexOf(",")){var b=a.indexOf(",");return[a.slice(5,b),a.substr(b+1)]}return[]}},m={"native":function(a,b,c){c(a)},image:a,"image/png;base64":a,"image/jpeg;base64":a,"image/jpg;base64":a},g={"export":h,
|
||||
"import":m,instance:q},k={init:function(a){return this.each(function(){var b,c=!1;for(b=this.parentNode;b&&!c;)c=b.body,b=b.parentNode;c&&new v(this,a,q)})},getSettings:function(){return this.find("canvas."+f).add(this.filter("canvas."+f)).data(f+".this").settings},isModified:function(){return null!==this.find("canvas."+f).add(this.filter("canvas."+f)).data(f+".this").dataEngine._stroke},updateSetting:function(a,b,c){var d=this.find("canvas."+f).add(this.filter("canvas."+f)).data(f+".this");d.settings[a]=
|
||||
b;d.resetCanvas(c?null:d.settings.data,!0);return d.settings[a]},clear:b,reset:b,addPlugin:function(a,b,c){g.hasOwnProperty(a)&&(g[a][b]=c);return this},listPlugins:function(a){var b=[];if(g.hasOwnProperty(a)){a=g[a];for(var c in a)a.hasOwnProperty(c)&&b.push(c)}return b},getData:function(a){var b=this.find("canvas."+f).add(this.filter("canvas."+f));void 0===a&&(a="default");if(0!==b.length&&h.hasOwnProperty(a))return h[a].call(b.get(0),b.data(f+".data"),b.data(f+".settings"))},importData:d,setData:d,
|
||||
globalEvents:function(){return e},disable:function(){this.find("input").attr("disabled",1);this.find("canvas."+f).addClass("disabled").data(f+".this").settings.readOnly=!0},enable:function(){this.find("input").removeAttr("disabled");this.find("canvas."+f).removeClass("disabled").data(f+".this").settings.readOnly=!1},events:function(){return this.find("canvas."+f).add(this.filter("canvas."+f)).data(f+".this").events}};$.fn[f]=function(a){if(a&&"object"!==typeof a){if("string"===typeof a&&k[a])return k[a].apply(this,
|
||||
Array.prototype.slice.call(arguments,1));$.error("Method "+String(a)+" does not exist on jQuery."+f)}else return k.init.apply(this,arguments)}})(window)})();
|
||||
(function(){function r(k,g,n){k=k.call(this);(function(g,k,n){g.events.subscribe(n+".change",function(){g.dataEngine.data.length?k.show():k.hide()})})(this,k,g);(function(g,k,n){var f=n+".undo";k.bind("click",function(){g.events.publish(f)});g.events.subscribe(f,function(){var f=g.dataEngine.data;f.length&&(f.pop(),g.resetCanvas(f))})})(this,k,this.events.topics.hasOwnProperty(g+".undo")?n:g)}$.fn.jSignature("addPlugin","instance","UndoButton",function(k){this.events.subscribe("jSignature.attachingEventHandlers",
|
||||
function(){if(this.settings[k]){var g=this.settings[k];"function"!==typeof g&&(g=function(){var g=$('<input type="button" value="Undo last stroke" style="position:absolute;display:none;margin:0 !important;top:auto" />').appendTo(this.$controlbarLower),k=g.width();g.css("left",Math.round((this.canvas.width-k)/2));k!==g.width()&&g.width(k);return g});r.call(this,g,"jSignature",k)}})})})();
|
||||
(function(){for(var r={},k={},g="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX".split(""),n=g.length/2,s=n-1;-1<s;s--)r[g[s]]=g[s+n],k[g[s+n]]=g[s];var v=function(f){f=f.split("");for(var e=f.length,c=1;c<e;c++)f[c]=r[f[c]];return f.join("")},w=function(f){for(var e=[],c=0,a=1,b=f.length,d,l,g=0;g<b;g++)d=Math.round(f[g]),l=d-c,c=d,0>l&&0<a?(a=-1,e.push("Z")):0<l&&0>a&&(a=1,e.push("Y")),d=Math.abs(l),d>=n?e.push(v(d.toString(n))):e.push(d.toString(n));return e.join("")},f=function(f){var e=
|
||||
[];f=f.split("");for(var c=f.length,a,b=1,d=[],l=0,g=0;g<c;g++)a=f[g],a in r||"Z"===a||"Y"===a?(0!==d.length&&(d=parseInt(d.join(""),n)*b+l,e.push(d),l=d),"Z"===a?(b=-1,d=[]):"Y"===a?(b=1,d=[]):d=[a]):d.push(k[a]);e.push(parseInt(d.join(""),n)*b+l);return e},u=function(f){for(var e=[],c=f.length,a,b=0;b<c;b++)a=f[b],e.push(w(a.x)),e.push(w(a.y));return e.join("_")},t=function(g){var e=[];g=g.split("_");for(var c=g.length/2,a=0;a<c;a++)e.push({x:f(g[2*a]),y:f(g[2*a+1])});return e},y=function(f){return["image/jsignature;base30",
|
||||
u(f)]},C=function(f,e,c){"string"===typeof f&&("image/jsignature;base30"===f.substring(0,23).toLowerCase()&&(f=f.substring(24)),c(t(f)))};if(null==this.jQuery)throw Error("We need jQuery for some of the functionality. jQuery is not detected. Failing to initialize...");(function(f){f=f.fn.jSignature;f("addPlugin","export","base30",y);f("addPlugin","export","image/jsignature;base30",y);f("addPlugin","import","base30",C);f("addPlugin","import","image/jsignature;base30",C)})(this.jQuery);this.jSignatureDebug&&
|
||||
(this.jSignatureDebug.base30={remapTailChars:v,compressstrokeleg:w,uncompressstrokeleg:f,compressstrokes:u,uncompressstrokes:t,charmap:r})}).call("undefined"!==typeof window?window:this);
|
||||
(function(){function r(e,c){this.x=e;this.y=c;this.reverse=function(){return new this.constructor(-1*this.x,-1*this.y)};this._length=null;this.getLength=function(){this._length||(this._length=Math.sqrt(Math.pow(this.x,2)+Math.pow(this.y,2)));return this._length};var a=function(a){return Math.round(a/Math.abs(a))};this.resizeTo=function(b){if(0===this.x&&0===this.y)this._length=0;else if(0===this.x)this._length=b,this.y=b*a(this.y);else if(0===this.y)this._length=b,this.x=b*a(this.x);else{var c=Math.abs(this.y/
|
||||
this.x),e=Math.sqrt(Math.pow(b,2)/(1+Math.pow(c,2))),c=c*e;this._length=b;this.x=e*a(this.x);this.y=c*a(this.y)}return this};this.angleTo=function(a){var c=this.getLength()*a.getLength();return 0===c?0:Math.acos(Math.min(Math.max((this.x*a.x+this.y*a.y)/c,-1),1))/Math.PI}}function k(e,c){this.x=e;this.y=c;this.getVectorToCoordinates=function(a,b){return new r(a-this.x,b-this.y)};this.getVectorFromCoordinates=function(a,b){return this.getVectorToCoordinates(a,b).reverse()};this.getVectorToPoint=function(a){return new r(a.x-
|
||||
this.x,a.y-this.y)};this.getVectorFromPoint=function(a){return this.getVectorToPoint(a).reverse()}}function g(e,c){var a=Math.pow(10,c);return Math.round(e*a)/a}function n(e,c,a){c+=1;var b=new k(e.x[c-1],e.y[c-1]),d=new k(e.x[c],e.y[c]),d=b.getVectorToPoint(d),f=new k(e.x[c-2],e.y[c-2]),b=f.getVectorToPoint(b);return b.getLength()>a?(a=2<c?(new k(e.x[c-3],e.y[c-3])).getVectorToPoint(f):new r(0,0),e=0.35*b.getLength(),f=b.angleTo(a.reverse()),c=d.angleTo(b.reverse()),a=(new r(a.x+b.x,a.y+b.y)).resizeTo(Math.max(0.05,
|
||||
f)*e),d=(new r(b.x+d.x,b.y+d.y)).reverse().resizeTo(Math.max(0.05,c)*e),d=new r(b.x+d.x,b.y+d.y),["c",g(a.x,2),g(a.y,2),g(d.x,2),g(d.y,2),g(b.x,2),g(b.y,2)]):["l",g(b.x,2),g(b.y,2)]}function s(e,c){var a=e.x.length-1,b=new k(e.x[a],e.y[a]),d=new k(e.x[a-1],e.y[a-1]),b=d.getVectorToPoint(b);if(1<a&&b.getLength()>c){var a=(new k(e.x[a-2],e.y[a-2])).getVectorToPoint(d),d=b.angleTo(a.reverse()),f=0.35*b.getLength(),a=(new r(a.x+b.x,a.y+b.y)).resizeTo(Math.max(0.05,d)*f);return["c",g(a.x,2),g(a.y,2),g(b.x,
|
||||
2),g(b.y,2),g(b.x,2),g(b.y,2)]}return["l",g(b.x,2),g(b.y,2)]}function v(e,c,a){c=["M",g(e.x[0]-c,2),g(e.y[0]-a,2)];a=1;for(var b=e.x.length-1;a<b;a++)c.push.apply(c,n(e,a,1));0<b?c.push.apply(c,s(e,a,1)):0===b&&c.push.apply(c,["l",1,1]);return c.join(" ")}function w(e){for(var c=[],a=[["fill",void 0,"none"],["stroke","color","#000000"],["stroke-width","lineWidth",2],["stroke-linecap",void 0,"round"],["stroke-linejoin",void 0,"round"]],b=a.length-1;0<=b;b--){var d=a[b][1],f=a[b][2];c.push(a[b][0]+
|
||||
'="'+(d in e&&e[d]?e[d]:f)+'"')}return c.join(" ")}function f(e,c){var a=['<?xml version="1.0" encoding="UTF-8" standalone="no"?>','<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'],b,d=e.length,f,g=[],h=[],m=f=b=0,k=0,n=[];if(0!==d){for(b=0;b<d;b++){m=e[b];k=[];f={x:[],y:[]};for(var p=void 0,q=void 0,p=0,q=m.x.length;p<q;p++)k.push({x:m.x[p],y:m.y[p]});k=simplify(k,0.7,!0);p=0;for(q=k.length;p<q;p++)f.x.push(k[p].x),f.y.push(k[p].y);n.push(f);g=
|
||||
g.concat(f.x);h=h.concat(f.y)}d=Math.min.apply(null,g)-1;b=Math.max.apply(null,g)+1;g=Math.min.apply(null,h)-1;h=Math.max.apply(null,h)+1;m=0>d?0:d;k=0>g?0:g;b-=d;f=h-g}a.push('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="'+b.toString()+'" height="'+f.toString()+'">');b=0;for(d=n.length;b<d;b++)f=n[b],a.push("<path "+w(c)+' d="'+v(f,m,k)+'"/>');a.push("</svg>");return a.join("")}function u(e,c){return[C,f(e,c)]}function t(e,c){return[q,y(f(e,c))]}(function(e,c){"use strict";(typeof exports!=
|
||||
c+""?exports:e).simplify=function(a,b,d){b=b!==c?b*b:1;if(!d){var e=a.length,f,g=a[0],m=[g];for(d=1;d<e;d++){f=a[d];var k=f.x-g.x,n=f.y-g.y;k*k+n*n>b&&(m.push(f),g=f)}a=(g!==f&&m.push(f),m)}f=a;d=f.length;var e=new (typeof Uint8Array!=c+""?Uint8Array:Array)(d),g=0,m=d-1,p,q,r=[],s=[],y=[];for(e[g]=e[m]=1;m;){n=0;for(k=g+1;k<m;k++){p=f[k];var z=f[g],v=f[m],t=z.x,u=z.y,z=v.x-t,B=v.y-u,w=void 0;if(0!==z||0!==B)w=((p.x-t)*z+(p.y-u)*B)/(z*z+B*B),1<w?(t=v.x,u=v.y):0<w&&(t+=z*w,u+=B*w);p=(z=p.x-t,B=p.y-
|
||||
u,z*z+B*B);p>n&&(q=k,n=p)}n>b&&(e[q]=1,r.push(g),s.push(q),r.push(q),s.push(m));g=r.pop();m=s.pop()}for(k=0;k<d;k++)e[k]&&y.push(f[k]);return a=y,a}})(window);if("function"!==typeof y)var y=function(e){var c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split(""),a,b,d,f,g=0,h=0,k="",k=[];do a=e.charCodeAt(g++),b=e.charCodeAt(g++),d=e.charCodeAt(g++),f=a<<16|b<<8|d,a=f>>18&63,b=f>>12&63,d=f>>6&63,f&=63,k[h++]=c[a]+c[b]+c[d]+c[f];while(g<e.length);k=k.join("");e=e.length%3;return(e?
|
||||
k.slice(0,e-3):k)+"===".slice(e||3)};var C="image/svg+xml",q="image/svg+xml;base64";if("undefined"===typeof $)throw Error("We need jQuery for some of the functionality. jQuery is not detected. Failing to initialize...");(function(e){e=e.fn.jSignature;e("addPlugin","export","svg",u);e("addPlugin","export",C,u);e("addPlugin","export","svgbase64",t);e("addPlugin","export",q,t)})($)})();
|
||||
|
|
@ -409,8 +409,22 @@ textarea.form-control {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.input-upload {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.uploaded-filename {
|
||||
border: 1px solid @border-color;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.uploaded-filename .btn-group {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.uploaded-filename-display {
|
||||
max-width: 194px;
|
||||
max-width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -534,6 +548,9 @@ textarea.form-control {
|
|||
max-height: 300px;
|
||||
overflow: auto;
|
||||
}
|
||||
.note-image-input {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// hide some buttons in modal
|
||||
|
|
|
|||
|
|
@ -538,6 +538,39 @@ h6.uppercase, .h6.uppercase {
|
|||
}
|
||||
}
|
||||
|
||||
.signature-field {
|
||||
min-height: 300px;
|
||||
background: #fff;
|
||||
border: 1px solid @border-color;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.signature-display {
|
||||
margin: 7px 0px;
|
||||
background: #fff;
|
||||
}
|
||||
.signature-btn-row {
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
.signature-reset {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding: 4px 0px;
|
||||
}
|
||||
|
||||
.signature-img {
|
||||
border: 1px solid @border-color;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
margin-top: 5px;
|
||||
width: 100%;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
|
||||
.timeline-new-email {
|
||||
margin: 30px 0px;
|
||||
padding-left: 70px;
|
||||
|
|
@ -603,18 +636,6 @@ h6.uppercase, .h6.uppercase {
|
|||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.linked-with-dialog {
|
||||
width: 75%;
|
||||
|
||||
.panel-body {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.attach-missing-image,
|
||||
.attach-image-display {
|
||||
cursor: pointer;
|
||||
|
|
|
|||
|
|
@ -483,6 +483,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.list-item-table {
|
||||
border: 1px solid @border-color;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -220,10 +220,6 @@ body {
|
|||
margin-left: 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.linked-with-dialog {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 767px) {
|
||||
|
|
|
|||
|
|
@ -286,6 +286,7 @@ class Session:
|
|||
"""get session record, or return the standard Guest Record"""
|
||||
from frappe.auth import clear_cookies
|
||||
r = self.get_session_data()
|
||||
|
||||
if not r:
|
||||
frappe.response["session_expired"] = 1
|
||||
clear_cookies()
|
||||
|
|
|
|||
47
frappe/templates/includes/integrations/stripe_checkout.js
Normal file
47
frappe/templates/includes/integrations/stripe_checkout.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
$(document).ready(function(){
|
||||
(function(e){
|
||||
var handler = StripeCheckout.configure({
|
||||
key: "{{ publishable_key }}",
|
||||
token: function(token) {
|
||||
// You can access the token ID with `token.id`.
|
||||
// Get the token ID to your server-side code for use.
|
||||
stripe.make_payment_log(token, {{ frappe.form_dict|json }}, "{{ reference_doctype }}", "{{ reference_docname }}");
|
||||
}
|
||||
});
|
||||
|
||||
handler.open({
|
||||
name: "{{payer_name}}",
|
||||
description: "{{description}}",
|
||||
amount: cint("{{ amount }}" * 100), // 2000 paise = INR 20
|
||||
email: "{{payer_email}}",
|
||||
currency: "{{currency}}"
|
||||
});
|
||||
|
||||
})();
|
||||
})
|
||||
|
||||
frappe.provide('stripe');
|
||||
|
||||
stripe.make_payment_log = function(token, data, doctype, docname){
|
||||
$('.stripe-loading').addClass('hidden');
|
||||
$('.stripe-confirming').removeClass('hidden');
|
||||
frappe.call({
|
||||
method:"frappe.templates.pages.integrations.stripe_checkout.make_payment",
|
||||
freeze:true,
|
||||
headers: {"X-Requested-With": "XMLHttpRequest"},
|
||||
args: {
|
||||
"stripe_token_id": token.id,
|
||||
"data": JSON.stringify(data),
|
||||
"reference_doctype": doctype,
|
||||
"reference_docname": docname
|
||||
},
|
||||
callback: function(r){
|
||||
if (r.message && r.message.status == 200) {
|
||||
window.location.href = r.message.redirect_to
|
||||
}
|
||||
else if (r.message && ([401,400,500].indexOf(r.message.status) > -1)) {
|
||||
window.location.href = r.message.redirect_to
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -170,11 +170,12 @@ login.login_handlers = (function() {
|
|||
window.location.href = data.home_page;
|
||||
}
|
||||
} else if(window.location.hash === '#forgot') {
|
||||
console.log(data.message);
|
||||
if(data.message==='not found') {
|
||||
login.set_indicator(__("Not a valid user"), 'red');
|
||||
} else if (data.message=='not allowed') {
|
||||
login.set_indicator(__("Not Allowed"), 'red');
|
||||
} else {
|
||||
login.set_indicator(__("Instructions Emailed"), 'green');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
28
frappe/templates/pages/integrations/stripe_checkout.html
Normal file
28
frappe/templates/pages/integrations/stripe_checkout.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block title %} Payment {% endblock %}
|
||||
|
||||
{%- block header -%}{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script src="https://checkout.stripe.com/checkout.js"></script>
|
||||
<script>{% include "templates/includes/integrations/stripe_checkout.js" %}</script>
|
||||
{% endblock %}
|
||||
|
||||
{%- block page_content -%}
|
||||
|
||||
<p class='lead text-center centered'>
|
||||
<span class='stripe-loading'>Loading Payment System</span>
|
||||
<span class='stripe-confirming hidden'>Confirming Payment</span>
|
||||
</p>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
<style>
|
||||
header, footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
49
frappe/templates/pages/integrations/stripe_checkout.py
Normal file
49
frappe/templates/pages/integrations/stripe_checkout.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, cint
|
||||
import json
|
||||
|
||||
no_cache = 1
|
||||
no_sitemap = 1
|
||||
|
||||
expected_keys = ('amount', 'title', 'description', 'reference_doctype', 'reference_docname',
|
||||
'payer_name', 'payer_email', 'order_id', 'currency')
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
context.publishable_key = get_api_key()
|
||||
|
||||
# all these keys exist in form_dict
|
||||
if not (set(expected_keys) - set(frappe.form_dict.keys())):
|
||||
for key in expected_keys:
|
||||
context[key] = frappe.form_dict[key]
|
||||
|
||||
context['amount'] = flt(context['amount'])
|
||||
|
||||
else:
|
||||
frappe.redirect_to_message(_('Some information is missing'),
|
||||
_('Looks like someone sent you to an incomplete URL. Please ask them to look into it.'))
|
||||
frappe.local.flags.redirect_location = frappe.local.response.location
|
||||
raise frappe.Redirect
|
||||
|
||||
def get_api_key():
|
||||
publishable_key = frappe.db.get_value("Stripe Settings", None, "publishable_key")
|
||||
if cint(frappe.form_dict.get("use_sandbox")):
|
||||
publishable_key = frappe.conf.sandbox_publishable_key
|
||||
|
||||
return publishable_key
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def make_payment(stripe_token_id, data, reference_doctype=None, reference_docname=None):
|
||||
data = json.loads(data)
|
||||
|
||||
data.update({
|
||||
"stripe_token_id": stripe_token_id
|
||||
})
|
||||
|
||||
data = frappe.get_doc("Stripe Settings").create_request(data)
|
||||
frappe.db.commit()
|
||||
return data
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
<div>{{ frappe.render_template(df.options, {"doc": doc}) or "" }}</div>
|
||||
{%- elif df.fieldtype in ("Text", "Text Editor", "Code") -%}
|
||||
{{ render_text_field(df, doc) }}
|
||||
{%- elif df.fieldtype in ("Image", "Attach Image", "Attach")
|
||||
{%- elif df.fieldtype in ("Image", "Attach Image", "Attach", "Signature")
|
||||
and (guess_mimetype(doc[df.fieldname])[0] or "").startswith("image/") -%}
|
||||
{{ render_image(df, doc) }}
|
||||
{%- else -%}
|
||||
|
|
@ -94,7 +94,6 @@ data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
|
|||
{%- endmacro -%}
|
||||
|
||||
{%- macro render_image(df, doc) -%}
|
||||
{%- if df.label %}<label>{{ _(df.label) }}</label>{%- endif %}
|
||||
{{ print_value(df, doc) }}
|
||||
{% endmacro %}
|
||||
|
||||
|
|
@ -108,6 +107,8 @@ data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
|
|||
<img src="{{ doc[doc.meta.get_field(df.fieldname).options] }}"
|
||||
class="img-responsive"
|
||||
{%- if df.print_width %} style="width: {{ get_width(df) }};"{% endif %}>
|
||||
{% elif df.fieldtype=="Signature" %}
|
||||
<img src="{{ doc[df.fieldname] }}" class="signature-img img-responsive">
|
||||
{% elif df.fieldtype in ("Attach", "Attach Image") and doc[df.fieldname]
|
||||
and (guess_mimetype(doc[df.fieldname])[0] or "").startswith("image/") %}
|
||||
<img src="{{ doc[df.fieldname] }}" class="img-responsive"
|
||||
|
|
|
|||
0
frappe/translations/en-GB.csv
Normal file
0
frappe/translations/en-GB.csv
Normal file
|
|
|
|
@ -28,7 +28,7 @@ def enqueue(method, queue='default', timeout=300, event=None,
|
|||
:param now: if now=True, the method is executed via frappe.call
|
||||
:param kwargs: keyword arguments to be passed to the method
|
||||
'''
|
||||
if now:
|
||||
if now or frappe.flags.in_migrate:
|
||||
return frappe.call(method, **kwargs)
|
||||
|
||||
q = get_queue(queue, async=async)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ def upload():
|
|||
"name": filedata.name,
|
||||
"file_name": filedata.file_name,
|
||||
"file_url": filedata.file_url,
|
||||
"is_private": filedata.is_private,
|
||||
"comment": comment.as_dict() if comment else {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ def get_context(context):
|
|||
context.parents = self.get_parents(context)
|
||||
|
||||
if self.breadcrumbs:
|
||||
context.parents = eval(self.breadcrumbs)
|
||||
context.parents = frappe.safe_eval(self.breadcrumbs)
|
||||
|
||||
context.has_header = ((frappe.form_dict.name or frappe.form_dict.new)
|
||||
and (frappe.session.user!="Guest" or not self.login_required))
|
||||
|
|
|
|||
|
|
@ -148,9 +148,9 @@ def get_html(doc, name=None, print_format=None, meta=None,
|
|||
"footer": letter_head.footer,
|
||||
"print_settings": frappe.get_doc("Print Settings")
|
||||
}
|
||||
|
||||
|
||||
html = template.render(args, filters={"len": len})
|
||||
|
||||
|
||||
if cint(trigger_print):
|
||||
html += trigger_print_script
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue