Merge branch 'develop' into ldap-multiple-email
This commit is contained in:
commit
2201601170
18 changed files with 187 additions and 111 deletions
|
|
@ -33,7 +33,6 @@
|
|||
"allow_guests_to_upload_files",
|
||||
"security",
|
||||
"session_expiry",
|
||||
"session_expiry_mobile",
|
||||
"document_share_key_expiry",
|
||||
"column_break_13",
|
||||
"deny_multiple_sessions",
|
||||
|
|
@ -211,13 +210,6 @@
|
|||
"fieldtype": "Data",
|
||||
"label": "Session Expiry (idle timeout)"
|
||||
},
|
||||
{
|
||||
"default": "720:00",
|
||||
"description": "In Hours",
|
||||
"fieldname": "session_expiry_mobile",
|
||||
"fieldtype": "Data",
|
||||
"label": "Session Expiry Mobile"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break"
|
||||
|
|
@ -517,7 +509,7 @@
|
|||
"icon": "fa fa-cog",
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-11-20 17:57:05.099512",
|
||||
"modified": "2022-11-28 17:57:05.099512",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Core",
|
||||
"name": "System Settings",
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@ class SystemSettings(Document):
|
|||
elif not enable_password_policy:
|
||||
self.minimum_password_score = ""
|
||||
|
||||
for key in ("session_expiry", "session_expiry_mobile"):
|
||||
if self.get(key):
|
||||
parts = self.get(key).split(":")
|
||||
if len(parts) != 2 or not (cint(parts[0]) or cint(parts[1])):
|
||||
frappe.throw(_("Session Expiry must be in format {0}").format("hh:mm"))
|
||||
if self.session_expiry:
|
||||
parts = self.session_expiry.split(":")
|
||||
if len(parts) != 2 or not (cint(parts[0]) or cint(parts[1])):
|
||||
frappe.throw(_("Session Expiry must be in format {0}").format("hh:mm"))
|
||||
|
||||
if self.enable_two_factor_auth:
|
||||
if self.two_factor_method == "SMS":
|
||||
|
|
|
|||
|
|
@ -252,7 +252,6 @@ CREATE TABLE `tabSessions` (
|
|||
`sessiondata` longtext,
|
||||
`ipaddress` varchar(16) DEFAULT NULL,
|
||||
`lastupdate` datetime(6) DEFAULT NULL,
|
||||
`device` varchar(255) DEFAULT 'desktop',
|
||||
`status` varchar(20) DEFAULT NULL,
|
||||
KEY `sid` (`sid`)
|
||||
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC CHARACTER SET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@ def check_compatible_versions():
|
|||
version = get_mariadb_version()
|
||||
version_tuple = tuple(int(v) for v in version[0].split("."))
|
||||
|
||||
if version_tuple < (10, 3):
|
||||
if version_tuple < (10, 6):
|
||||
click.secho(
|
||||
f"Warning: MariaDB version {version} is less than 10.3 which is not supported by Frappe",
|
||||
f"Warning: MariaDB version {version} is less than 10.6 which is not supported by Frappe",
|
||||
fg="yellow",
|
||||
)
|
||||
elif version_tuple >= (10, 9):
|
||||
|
|
|
|||
|
|
@ -256,7 +256,6 @@ CREATE TABLE "tabSessions" (
|
|||
"sessiondata" text,
|
||||
"ipaddress" varchar(16) DEFAULT NULL,
|
||||
"lastupdate" timestamp(6) DEFAULT NULL,
|
||||
"device" varchar(255) DEFAULT 'desktop',
|
||||
"status" varchar(20) DEFAULT NULL
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,9 @@ class FormMeta(Meta):
|
|||
list_script = ""
|
||||
form_script = ""
|
||||
for script in client_scripts:
|
||||
if not script.script:
|
||||
continue
|
||||
|
||||
if script.view == "List":
|
||||
list_script += f"""
|
||||
// {script.name}
|
||||
|
|
@ -163,7 +166,7 @@ class FormMeta(Meta):
|
|||
|
||||
"""
|
||||
|
||||
if script.view == "Form":
|
||||
elif script.view == "Form":
|
||||
form_script += f"""
|
||||
// {script.name}
|
||||
{script.script}
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ def format_duration_fields(data: frappe._dict) -> None:
|
|||
continue
|
||||
|
||||
for row in data.result:
|
||||
index = col.fieldname if isinstance(row, dict) else i
|
||||
index = col.get("fieldname") if isinstance(row, dict) else i
|
||||
if row[index]:
|
||||
row[index] = format_duration(row[index])
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ def get_countries_and_currencies():
|
|||
countries = []
|
||||
currencies = []
|
||||
|
||||
added_currencies = set()
|
||||
|
||||
for name, country in data.items():
|
||||
country = frappe._dict(country)
|
||||
countries.append(
|
||||
|
|
@ -42,7 +44,9 @@ def get_countries_and_currencies():
|
|||
time_zones="\n".join(country.timezones or []),
|
||||
)
|
||||
)
|
||||
if country.currency:
|
||||
if country.currency and country.currency not in added_currencies:
|
||||
added_currencies.add(country.currency)
|
||||
|
||||
currencies.append(
|
||||
frappe.get_doc(
|
||||
doctype="Currency",
|
||||
|
|
|
|||
|
|
@ -708,17 +708,16 @@ class Document(BaseDocument):
|
|||
d.reset_values_if_no_permlevel_access(has_access_to, high_permlevel_fields)
|
||||
|
||||
def get_permlevel_access(self, permission_type="write"):
|
||||
if not hasattr(self, "_has_access_to"):
|
||||
self._has_access_to = {}
|
||||
|
||||
self._has_access_to[permission_type] = []
|
||||
allowed_permlevels = []
|
||||
roles = frappe.get_roles()
|
||||
for perm in self.get_permissions():
|
||||
if perm.role in roles and perm.get(permission_type):
|
||||
if perm.permlevel not in self._has_access_to[permission_type]:
|
||||
self._has_access_to[permission_type].append(perm.permlevel)
|
||||
|
||||
return self._has_access_to[permission_type]
|
||||
for perm in self.get_permissions():
|
||||
if (
|
||||
perm.role in roles and perm.get(permission_type) and perm.permlevel not in allowed_permlevels
|
||||
):
|
||||
allowed_permlevels.append(perm.permlevel)
|
||||
|
||||
return allowed_permlevels
|
||||
|
||||
def has_permlevel_access_to(self, fieldname, df=None, permission_type="read"):
|
||||
if not df:
|
||||
|
|
|
|||
|
|
@ -644,6 +644,8 @@ $.extend(frappe.model, {
|
|||
doctype: doctype,
|
||||
name: docname,
|
||||
},
|
||||
freeze: true,
|
||||
freeze_message: __("Deleting {0}...", [title]),
|
||||
callback: function (r, rt) {
|
||||
if (!r.exc) {
|
||||
frappe.utils.play_sound("delete");
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
// J<>rgen Tjern<72> - async helper
|
||||
// Anurag Awasthi - updated to 0.2.0
|
||||
|
||||
const SEQUENTIAL_BONUS = 15; // bonus for adjacent matches
|
||||
const SEQUENTIAL_BONUS = 25; // bonus for adjacent matches
|
||||
const SEPARATOR_BONUS = 30; // bonus if match occurs after a separator
|
||||
const CAMEL_BONUS = 30; // bonus if match is uppercase and prev is lower
|
||||
const FIRST_LETTER_BONUS = 15; // bonus if the first letter is matched
|
||||
|
|
|
|||
|
|
@ -379,7 +379,6 @@ export default class WebForm extends frappe.ui.FieldGroup {
|
|||
args: {
|
||||
data: this.doc,
|
||||
web_form: this.name,
|
||||
docname: this.doc.name,
|
||||
for_payment,
|
||||
},
|
||||
callback: (response) => {
|
||||
|
|
|
|||
117
frappe/query_builder/docs.md
Normal file
117
frappe/query_builder/docs.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# This documentation is added for query builder and related files.
|
||||
|
||||
## Related Files
|
||||
|
||||
- [builder](./builder.py)
|
||||
- [custom](./custom.py)
|
||||
- [functions](./functions.py)
|
||||
- [terms](./terms.py)
|
||||
- [query](../database/query.py)
|
||||
|
||||
### Builder
|
||||
|
||||
Database specefic classes are declared which are then selected during init to give either postgres or mariadb dialects.
|
||||
|
||||
### Functions and Custom
|
||||
|
||||
These file handle any custom function which needs to be either added or handled sperately by the different dialects which are not supported yet by pypika directly.
|
||||
|
||||
### Terms
|
||||
|
||||
The inherent terms or specefic classes of pypika builder are handled and declared here all the parameterization goes through this module (custom parameterization is also implemeted here).
|
||||
|
||||
### Raw Query Generation Examples
|
||||
|
||||
Check out some examples [here](https://frappeframework.com/docs/v14/user/en/api/query-builder)
|
||||
|
||||
<H2 align="center">Query</H2>
|
||||
|
||||
## Goal
|
||||
|
||||
```sql
|
||||
select `name` from `tabUser`
|
||||
```
|
||||
|
||||
## There are 3 major ways to reach this goal
|
||||
|
||||
### 1. Direct SQL (Boring / Unsafe / inconsistent)
|
||||
|
||||
```python
|
||||
frappe.db.sql("select `name` from `tabUser`")
|
||||
```
|
||||
|
||||
### 2. SQL through direct Query Builder objects
|
||||
|
||||
```python
|
||||
from frappe.query_builder import Field
|
||||
|
||||
frappe.qb.from_("User").select(Field("name"))
|
||||
|
||||
```
|
||||
|
||||
### 3. Through the database API (Which performs the second method under the hood)
|
||||
|
||||
```python
|
||||
frappe.db.get_values("User", fieldname="name", filters={})
|
||||
```
|
||||
|
||||
This module is used to support the 3rd way of query generation in frappe.
|
||||
The database module is completely powered by this query module.
|
||||
This module is also where the query `Engine` resides which is the class responsible for the handling of various filter & field notations.
|
||||
|
||||
- Interating with the existing Database API.
|
||||
- The old database API was running on raw sql generation in order to bridge the gap between the added new support and raw sql strings this intermediate module was added.
|
||||
|
||||
This module supports almost all the features present in db_query which powers `frappe.get_all` and `frappe.get_list`
|
||||
|
||||
Supporting all the features with the previous filter notations and the field notations few features were added -:
|
||||
|
||||
1. Dict Query
|
||||
|
||||
- To support this
|
||||
|
||||
```python
|
||||
frappe.db.get_values("ToDo", fieldname="name", filters={"description": "Something Random"})
|
||||
```
|
||||
|
||||
and many other possible caveats to the dict representation such as
|
||||
|
||||
```python
|
||||
frappe.db.get_values("User", fieldname="name",
|
||||
filters={"name": ("like", "admin%")})
|
||||
|
||||
frappe.db.get_values("ToDo", fieldname="name", filters={"description": ("in", ["somso%", "someome"])})
|
||||
```
|
||||
|
||||
2. Misc Query
|
||||
|
||||
- To support this
|
||||
|
||||
```python
|
||||
frappe.db.get_values("ToDo", fieldname="name", filters=["description", "=", "someone"])
|
||||
```
|
||||
|
||||
Along with other possible list filter use cases including implicit joins
|
||||
|
||||
3. Criterion Query
|
||||
|
||||
- To support Inherent Query Builder objects
|
||||
|
||||
```python
|
||||
from frappe.query_builder import Field
|
||||
|
||||
frappe.db.get_values("User", fieldname="name", filters=Field("name") == "Administrator")
|
||||
|
||||
```
|
||||
|
||||
and all the pypika filters and functions.
|
||||
|
||||
## Things to be implemented in the `Engine`
|
||||
|
||||
### 1. Support for Permissions
|
||||
|
||||
As of now query builder has no concept of permissions and moving towards a singular database API this needs to be added in the `Engine`.
|
||||
|
||||
### 2. Implementing the missing features which are present in `frappe.get_list` and `frappe.get_all` (do we even need so much magic?)
|
||||
|
||||
Moving to a singular Database API (database.py + db_query.py) all the support present in `get_list` and `get_all` needs to be present in the new `Engine` as well however this creates alot of security cracks, so moving the a *new and more restrictive version* of the database API with backward compatibility perhaps would be the right way to go?
|
||||
|
|
@ -32,12 +32,11 @@ def clear():
|
|||
frappe.response["message"] = _("Cache Cleared")
|
||||
|
||||
|
||||
def clear_sessions(user=None, keep_current=False, device=None, force=False):
|
||||
def clear_sessions(user=None, keep_current=False, force=False):
|
||||
"""Clear other sessions of the current user. Called at login / logout
|
||||
|
||||
:param user: user name (default: current user)
|
||||
:param keep_current: keep current session (default: false)
|
||||
:param device: delete sessions of this device (default: desktop, mobile)
|
||||
:param force: triggered by the user (default false)
|
||||
"""
|
||||
|
||||
|
|
@ -45,35 +44,26 @@ def clear_sessions(user=None, keep_current=False, device=None, force=False):
|
|||
if force:
|
||||
reason = "Force Logged out by the user"
|
||||
|
||||
for sid in get_sessions_to_clear(user, keep_current, device):
|
||||
for sid in get_sessions_to_clear(user, keep_current):
|
||||
delete_session(sid, reason=reason)
|
||||
|
||||
|
||||
def get_sessions_to_clear(user=None, keep_current=False, device=None):
|
||||
def get_sessions_to_clear(user=None, keep_current=False):
|
||||
"""Returns sessions of the current user. Called at login / logout
|
||||
|
||||
:param user: user name (default: current user)
|
||||
:param keep_current: keep current session (default: false)
|
||||
:param device: delete sessions of this device (default: desktop, mobile)
|
||||
"""
|
||||
if not user:
|
||||
user = frappe.session.user
|
||||
|
||||
if not device:
|
||||
device = ("desktop", "mobile")
|
||||
|
||||
if not isinstance(device, (tuple, list)):
|
||||
device = (device,)
|
||||
|
||||
offset = 0
|
||||
if user == frappe.session.user:
|
||||
simultaneous_sessions = frappe.db.get_value("User", user, "simultaneous_sessions") or 1
|
||||
offset = simultaneous_sessions - 1
|
||||
|
||||
session = DocType("Sessions")
|
||||
session_id = frappe.qb.from_(session).where(
|
||||
(session.user == user) & (session.device.isin(device))
|
||||
)
|
||||
session_id = frappe.qb.from_(session).where(session.user == user)
|
||||
if keep_current:
|
||||
session_id = session_id.where(session.sid != frappe.session.sid)
|
||||
|
||||
|
|
@ -121,25 +111,18 @@ def clear_all_sessions(reason=None):
|
|||
|
||||
def get_expired_sessions():
|
||||
"""Returns list of expired sessions"""
|
||||
|
||||
sessions = DocType("Sessions")
|
||||
|
||||
expired = []
|
||||
for device in ("desktop", "mobile"):
|
||||
expired.extend(
|
||||
frappe.db.get_values(
|
||||
sessions,
|
||||
filters=(
|
||||
PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})")
|
||||
> get_expiry_period_for_query(device)
|
||||
)
|
||||
& (sessions.device == device),
|
||||
fieldname="sid",
|
||||
order_by=None,
|
||||
pluck=True,
|
||||
)
|
||||
)
|
||||
|
||||
return expired
|
||||
return frappe.db.get_values(
|
||||
sessions,
|
||||
filters=(
|
||||
PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") > get_expiry_period_for_query()
|
||||
),
|
||||
fieldname="sid",
|
||||
order_by=None,
|
||||
pluck=True,
|
||||
)
|
||||
|
||||
|
||||
def clear_expired_sessions():
|
||||
|
|
@ -218,14 +201,13 @@ def generate_csrf_token():
|
|||
|
||||
|
||||
class Session:
|
||||
__slots__ = ("user", "device", "user_type", "full_name", "data", "time_diff", "sid")
|
||||
__slots__ = ("user", "user_type", "full_name", "data", "time_diff", "sid")
|
||||
|
||||
def __init__(self, user, resume=False, full_name=None, user_type=None):
|
||||
self.sid = cstr(
|
||||
frappe.form_dict.get("sid") or unquote(frappe.request.cookies.get("sid", "Guest"))
|
||||
)
|
||||
self.user = user
|
||||
self.device = frappe.form_dict.get("device") or "desktop"
|
||||
self.user_type = user_type
|
||||
self.full_name = full_name
|
||||
self.data = frappe._dict({"data": frappe._dict({})})
|
||||
|
|
@ -257,10 +239,9 @@ class Session:
|
|||
self.data.data.update(
|
||||
{
|
||||
"last_updated": frappe.utils.now(),
|
||||
"session_expiry": get_expiry_period(self.device),
|
||||
"session_expiry": get_expiry_period(),
|
||||
"full_name": self.full_name,
|
||||
"user_type": self.user_type,
|
||||
"device": self.device,
|
||||
"session_country": get_geo_ip_country(frappe.local.request_ip)
|
||||
if frappe.local.request_ip
|
||||
else None,
|
||||
|
|
@ -289,9 +270,9 @@ class Session:
|
|||
def insert_session_record(self):
|
||||
frappe.db.sql(
|
||||
"""insert into `tabSessions`
|
||||
(`sessiondata`, `user`, `lastupdate`, `sid`, `status`, `device`)
|
||||
values (%s , %s, NOW(), %s, 'Active', %s)""",
|
||||
(str(self.data["data"]), self.data["user"], self.data["sid"], self.device),
|
||||
(`sessiondata`, `user`, `lastupdate`, `sid`, `status`)
|
||||
values (%s , %s, NOW(), %s, 'Active')""",
|
||||
(str(self.data["data"]), self.data["user"], self.data["sid"]),
|
||||
)
|
||||
|
||||
# also add to memcache
|
||||
|
|
@ -308,7 +289,6 @@ class Session:
|
|||
self.data.update({"data": data, "user": data.user, "sid": self.sid})
|
||||
self.user = data.user
|
||||
validate_ip_address(self.user)
|
||||
self.device = data.device
|
||||
else:
|
||||
self.start_as_guest()
|
||||
|
||||
|
|
@ -359,22 +339,11 @@ class Session:
|
|||
|
||||
def get_session_data_from_db(self):
|
||||
sessions = DocType("Sessions")
|
||||
|
||||
self.device = (
|
||||
frappe.db.get_value(
|
||||
sessions,
|
||||
filters=sessions.sid == self.sid,
|
||||
fieldname="device",
|
||||
order_by=None,
|
||||
)
|
||||
or "desktop"
|
||||
)
|
||||
rec = frappe.db.get_values(
|
||||
sessions,
|
||||
filters=(sessions.sid == self.sid)
|
||||
& (
|
||||
PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})")
|
||||
< get_expiry_period_for_query(self.device)
|
||||
PseudoColumn(f"({Now()} - {sessions.lastupdate.get_sql()})") < get_expiry_period_for_query()
|
||||
),
|
||||
fieldname=["user", "sessiondata"],
|
||||
order_by=None,
|
||||
|
|
@ -437,29 +406,23 @@ class Session:
|
|||
return updated_in_db
|
||||
|
||||
|
||||
def get_expiry_period_for_query(device=None):
|
||||
def get_expiry_period_for_query():
|
||||
if frappe.db.db_type == "postgres":
|
||||
return get_expiry_period(device)
|
||||
return get_expiry_period()
|
||||
else:
|
||||
return get_expiry_in_seconds(device=device)
|
||||
return get_expiry_in_seconds()
|
||||
|
||||
|
||||
def get_expiry_in_seconds(expiry=None, device=None):
|
||||
def get_expiry_in_seconds(expiry=None):
|
||||
if not expiry:
|
||||
expiry = get_expiry_period(device)
|
||||
expiry = get_expiry_period()
|
||||
|
||||
parts = expiry.split(":")
|
||||
return (cint(parts[0]) * 3600) + (cint(parts[1]) * 60) + cint(parts[2])
|
||||
|
||||
|
||||
def get_expiry_period(device="desktop"):
|
||||
if device == "mobile":
|
||||
key = "session_expiry_mobile"
|
||||
default = "720:00:00"
|
||||
else:
|
||||
key = "session_expiry"
|
||||
default = "06:00:00"
|
||||
|
||||
exp_sec = frappe.defaults.get_global_default(key) or default
|
||||
def get_expiry_period():
|
||||
exp_sec = frappe.defaults.get_global_default("session_expiry") or "06:00:00"
|
||||
|
||||
# incase seconds is missing
|
||||
if len(exp_sec.split(":")) == 2:
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ login.bind_events = function () {
|
|||
args.cmd = "login";
|
||||
args.usr = frappe.utils.xss_sanitise(($("#login_email").val() || "").trim());
|
||||
args.pwd = $("#login_password").val();
|
||||
args.device = "desktop";
|
||||
if (!args.usr || !args.pwd) {
|
||||
frappe.msgprint('{{ _("Both login and password required") }}');
|
||||
return false;
|
||||
|
|
@ -73,7 +72,6 @@ login.bind_events = function () {
|
|||
args.cmd = "{{ ldap_settings.method }}";
|
||||
args.usr = ($("#login_email").val() || "").trim();
|
||||
args.pwd = $("#login_password").val();
|
||||
args.device = "desktop";
|
||||
if (!args.usr || !args.pwd) {
|
||||
login.set_status('{{ _("Both login and password required") }}', 'red');
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ def before_tests():
|
|||
if not int(frappe.db.get_single_value("System Settings", "setup_complete") or 0):
|
||||
complete_setup_wizard()
|
||||
|
||||
frappe.db.set_value("Website Settings", "Website Settings", "disable_signup", 0)
|
||||
frappe.db.commit()
|
||||
frappe.clear_cache()
|
||||
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ def get_context(context):
|
|||
return False
|
||||
|
||||
if self.apply_document_permissions:
|
||||
return frappe.get_doc(doctype, name).has_permission()
|
||||
return frappe.get_doc(doctype, name).has_permission(permtype=ptype)
|
||||
|
||||
# owner matches
|
||||
elif frappe.db.get_value(doctype, name, "owner") == frappe.session.user:
|
||||
|
|
@ -365,7 +365,7 @@ def get_web_form_module(doc):
|
|||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@rate_limit(key="web_form", limit=5, seconds=60, methods=["POST"])
|
||||
def accept(web_form, data, docname=None):
|
||||
def accept(web_form, data):
|
||||
"""Save the web form"""
|
||||
data = frappe._dict(json.loads(data))
|
||||
|
||||
|
|
@ -373,19 +373,20 @@ def accept(web_form, data, docname=None):
|
|||
files_to_delete = []
|
||||
|
||||
web_form = frappe.get_doc("Web Form", web_form)
|
||||
doctype = web_form.doc_type
|
||||
|
||||
if data.name and not web_form.allow_edit:
|
||||
frappe.throw(_("You are not allowed to update this Web Form Document"))
|
||||
|
||||
frappe.flags.in_web_form = True
|
||||
meta = frappe.get_meta(data.doctype)
|
||||
meta = frappe.get_meta(doctype)
|
||||
|
||||
if docname:
|
||||
if data.name:
|
||||
# update
|
||||
doc = frappe.get_doc(data.doctype, docname)
|
||||
doc = frappe.get_doc(doctype, data.name)
|
||||
else:
|
||||
# insert
|
||||
doc = frappe.new_doc(data.doctype)
|
||||
doc = frappe.new_doc(doctype)
|
||||
|
||||
# set values
|
||||
for field in web_form.web_form_fields:
|
||||
|
|
@ -406,7 +407,7 @@ def accept(web_form, data, docname=None):
|
|||
doc.set(fieldname, value)
|
||||
|
||||
if doc.name:
|
||||
if web_form.has_web_form_permission(doc.doctype, doc.name, "write"):
|
||||
if web_form.has_web_form_permission(doctype, doc.name, "write"):
|
||||
doc.save(ignore_permissions=True)
|
||||
else:
|
||||
# only if permissions are present
|
||||
|
|
@ -428,7 +429,7 @@ def accept(web_form, data, docname=None):
|
|||
|
||||
# remove earlier attached file (if exists)
|
||||
if doc.get(fieldname):
|
||||
remove_file_by_url(doc.get(fieldname), doctype=doc.doctype, name=doc.name)
|
||||
remove_file_by_url(doc.get(fieldname), doctype=doctype, name=doc.name)
|
||||
|
||||
# save new file
|
||||
filename, dataurl = filedata.split(",", 1)
|
||||
|
|
@ -436,7 +437,7 @@ def accept(web_form, data, docname=None):
|
|||
{
|
||||
"doctype": "File",
|
||||
"file_name": filename,
|
||||
"attached_to_doctype": doc.doctype,
|
||||
"attached_to_doctype": doctype,
|
||||
"attached_to_name": doc.name,
|
||||
"content": dataurl,
|
||||
"decode": True,
|
||||
|
|
@ -452,7 +453,7 @@ def accept(web_form, data, docname=None):
|
|||
if files_to_delete:
|
||||
for f in files_to_delete:
|
||||
if f:
|
||||
remove_file_by_url(f, doctype=doc.doctype, name=doc.name)
|
||||
remove_file_by_url(f, doctype=doctype, name=doc.name)
|
||||
|
||||
frappe.flags.web_form_doc = doc
|
||||
return doc
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@
|
|||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"default": "1",
|
||||
"description": "Disable Customer Signup link in Login page",
|
||||
"fieldname": "disable_signup",
|
||||
"fieldtype": "Check",
|
||||
|
|
@ -476,7 +476,7 @@
|
|||
"index_web_pages_for_search": 1,
|
||||
"issingle": 1,
|
||||
"links": [],
|
||||
"modified": "2022-10-18 09:50:24.621839",
|
||||
"modified": "2022-12-05 04:17:56.478757",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Website Settings",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue