Initialize fork and rebrand app to event_manager
CI / Server (push) Has been cancelled
Linters / Frappe Linter (push) Has been cancelled
Linters / Vulnerable Dependency Check (push) Has been cancelled
UI Tests / Playwright E2E Tests (push) Has been cancelled

This commit is contained in:
2026-05-11 09:56:57 +02:00
parent f82bb803ac
commit 786cbc724f
500 changed files with 41152 additions and 2 deletions
+344
View File
@@ -0,0 +1,344 @@
from functools import lru_cache
import frappe
from frappe import _
from frappe.geo.country_info import get_all as get_all_countries
from frappe.model import DEFAULT_FIELDS, display_fieldtypes
from frappe.utils import get_datetime, now_datetime, today
from frappe.utils.data import cstr, sbool
LAYOUT_FIELDTYPES = set(display_fieldtypes)
EVENT_PROPOSAL_EXCLUDE_FIELDS = DEFAULT_FIELDS | {
"naming_series",
"amended_from",
"host",
"host_company",
"host_company_logo",
"additional_notes",
"status",
"submitted_by",
}
STANDARD_EXCLUDE_FIELDS = DEFAULT_FIELDS | {
"additional_fields",
"event",
"section_break_additional",
"submitted_by",
"status",
}
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
def get_dial_codes() -> list:
return _get_dial_codes()
@lru_cache(maxsize=1)
def _get_dial_codes() -> list:
data = get_all_countries()
codes = []
seen = set()
for country in sorted(data):
info = data[country]
isd = info.get("isd", "")
code = (info.get("code") or "").upper()
if isd and isd not in seen:
codes.append({"country": country, "code": code, "dial_code": isd})
seen.add(isd)
return codes
def get_form_fields(doctype: str, exclude_fields: set) -> list:
meta = frappe.get_meta(doctype)
fields = []
for df in meta.fields:
if df.fieldname in exclude_fields:
continue
if df.fieldtype in LAYOUT_FIELDTYPES:
continue
if df.hidden:
continue
if df.read_only:
continue
default_value = df.default
if default_value:
if default_value == "Today":
default_value = today()
elif default_value == "Now":
default_value = cstr(now_datetime())
elif default_value.startswith("eval:") or default_value.startswith("%"):
default_value = None
field_data = {
"fieldname": df.fieldname,
"fieldtype": df.fieldtype,
"label": df.label or df.fieldname,
"options": df.options,
"reqd": df.reqd,
"default": default_value,
"description": df.description,
}
if df.fieldtype == "Link" and df.options:
link_values = frappe.get_all(
df.options,
fields=["name"],
limit_page_length=0,
order_by="name asc",
)
field_data["link_options"] = [d.name for d in link_values]
if df.fieldtype == "Table" and df.options:
child_meta = frappe.get_meta(df.options)
child_fields = []
for child_df in child_meta.fields:
if child_df.fieldtype in LAYOUT_FIELDTYPES:
continue
if child_df.hidden:
continue
child_fields.append(
{
"fieldname": child_df.fieldname,
"fieldtype": child_df.fieldtype,
"label": child_df.label or child_df.fieldname,
"options": child_df.options,
"reqd": child_df.reqd,
}
)
field_data["child_fields"] = child_fields
fields.append(field_data)
return fields
def validate_custom_form(event_route: str, form_route: str):
event_name = frappe.get_cached_value("Pohodex Event Manager Event", {"route": event_route}, "name")
if not event_name:
frappe.throw(_("Event not found"), frappe.DoesNotExistError)
event_doc = frappe.get_cached_doc("Pohodex Event Manager Event", event_name)
if not event_doc.is_published:
frappe.throw(_("Event not found"), frappe.DoesNotExistError)
form_row = None
for row in event_doc.custom_forms:
if row.route == form_route and row.publish:
form_row = row
break
if not form_row:
frappe.throw(_("This form is not available for this event"), frappe.DoesNotExistError)
return event_doc, form_row
def get_auto_set_fields(form_doctype: str):
meta = frappe.get_meta(form_doctype)
auto_set = {}
for df in meta.fields:
if df.fieldname == "event" and df.fieldtype == "Link":
auto_set["event"] = "from_route"
elif df.fieldname == "submitted_by" and df.fieldtype == "Link":
auto_set["submitted_by"] = "session_user"
return auto_set
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
def get_custom_form_data(event_route: str, form_route: str) -> dict:
event_doc, form_row = validate_custom_form(event_route, form_route)
form_doctype = form_row.form_doctype
allow_guest_submission = sbool(event_doc.allow_guest_booking)
if not allow_guest_submission and frappe.session.user == "Guest":
frappe.throw(_("Please log in to submit this form"), frappe.AuthenticationError)
event_data = {
"name": event_doc.name,
"title": event_doc.title,
"route": event_doc.route,
"banner_image": event_doc.banner_image,
"start_date": event_doc.start_date,
"end_date": event_doc.end_date,
"start_time": event_doc.start_time,
"end_time": event_doc.end_time,
"time_zone": event_doc.time_zone,
"venue": event_doc.venue,
"medium": event_doc.medium,
"short_description": event_doc.short_description,
}
closed = False
if form_row.auto_close_at and get_datetime(form_row.auto_close_at) < now_datetime():
closed = True
if closed:
return {
"form_fields": [],
"custom_fields": [],
"form_title": form_doctype,
"event": event_data,
"closed": True,
"closed_title": form_row.closed_title or _("Submissions Closed"),
"closed_message": form_row.closed_message or _("Submissions for this form have closed."),
"success_title": "",
"success_message": "",
}
auto_set = get_auto_set_fields(form_doctype)
exclude_fields = STANDARD_EXCLUDE_FIELDS | set(auto_set.keys())
form_fields = get_form_fields(form_doctype, exclude_fields)
form_doctype_meta = frappe.get_meta(form_doctype)
custom_fields = []
if form_doctype_meta.has_field("additional_fields"):
custom_fields = frappe.get_all(
"Pohodex Event Manager Custom Field",
filters={
"event": event_doc.name,
"applied_to": "Custom Form",
"custom_form_doctype": form_doctype,
"enabled": 1,
},
fields=[
"label",
"fieldname",
"fieldtype",
"options",
"mandatory",
"placeholder",
"default_value",
"order",
],
order_by="order asc",
)
return {
"form_fields": form_fields,
"custom_fields": custom_fields,
"form_title": form_doctype_meta.name,
"event": event_data,
"closed": False,
"closed_title": form_row.closed_title or _("Submissions Closed"),
"closed_message": form_row.closed_message or _("Submissions for this form have closed."),
"success_title": form_row.success_title or _("Thank you!"),
"success_message": form_row.success_message or "",
}
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
def submit_custom_form(
event_route: str, form_route: str, data: dict | str, custom_fields_data: dict | str | None = None
) -> None:
event_doc, form_row = validate_custom_form(event_route, form_route)
form_doctype = form_row.form_doctype
if not event_doc.allow_guest_booking and frappe.session.user == "Guest":
frappe.throw(_("Please login to submit this form"), frappe.AuthenticationError)
if form_row.auto_close_at and get_datetime(form_row.auto_close_at) < now_datetime():
frappe.throw(_("Submissions for this form have closed."))
data = frappe.parse_json(data) or {}
custom_fields_data = frappe.parse_json(custom_fields_data) or {}
auto_set = get_auto_set_fields(form_doctype)
exclude_fields = STANDARD_EXCLUDE_FIELDS | set(auto_set.keys())
doc_data = {"doctype": form_doctype}
for field, source in auto_set.items():
if source == "from_route":
doc_data[field] = event_doc.name
elif source == "session_user":
doc_data[field] = frappe.session.user
allowed_fieldnames = {f["fieldname"] for f in get_form_fields(form_doctype, exclude_fields)}
for fieldname, value in data.items():
if fieldname in allowed_fieldnames:
doc_data[fieldname] = value
meta = frappe.get_meta(form_doctype)
for df in meta.fields:
if df.fieldtype == "Table" and df.fieldname not in exclude_fields:
if df.fieldname in data and isinstance(data[df.fieldname], list):
doc_data[df.fieldname] = data[df.fieldname]
doc = frappe.get_doc(doc_data)
if custom_fields_data and meta.has_field("additional_fields"):
custom_field_definitions = frappe.get_all(
"Pohodex Event Manager Custom Field",
filters={
"event": event_doc.name,
"applied_to": "Custom Form",
"custom_form_doctype": form_doctype,
"enabled": 1,
},
fields=["fieldname", "label", "fieldtype"],
)
allowed_custom = {cf["fieldname"]: cf for cf in custom_field_definitions}
for fieldname, value in custom_fields_data.items():
if fieldname in allowed_custom and value not in (None, ""):
cf = allowed_custom[fieldname]
doc.append(
"additional_fields",
{
"label": cf["label"],
"fieldname": fieldname,
"fieldtype": cf["fieldtype"],
"value": cstr(value),
},
)
doc.insert(ignore_permissions=True)
def validate_event_proposal_settings():
settings = frappe.get_cached_doc("Pohodex Event Manager Settings")
if not settings.accept_event_proposals:
frappe.throw(_("Event Proposals are not being accepted"), frappe.DoesNotExistError)
if not settings.allow_guest_event_proposals and frappe.session.user == "Guest":
frappe.throw(_("Please log in to submit a proposal"), frappe.AuthenticationError)
return settings
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
def get_event_proposal_form_data() -> dict:
settings = validate_event_proposal_settings()
form_fields = get_form_fields("Event Proposal", EVENT_PROPOSAL_EXCLUDE_FIELDS)
return {
"form_fields": form_fields,
"form_title": _("Event Proposal"),
"banner_title": settings.event_proposal_banner_title or _("Propose an Event"),
"success_title": settings.event_proposal_success_title or _("Thank you!"),
"success_message": settings.event_proposal_success_message or "",
}
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
def submit_event_proposal(data: dict | str) -> None:
validate_event_proposal_settings()
data = frappe.parse_json(data) or {}
doc_data = {"doctype": "Event Proposal"}
if frappe.session.user != "Guest":
doc_data["submitted_by"] = frappe.session.user
allowed_fieldnames = {
f["fieldname"] for f in get_form_fields("Event Proposal", EVENT_PROPOSAL_EXCLUDE_FIELDS)
}
for fieldname, value in data.items():
if fieldname in allowed_fieldnames:
doc_data[fieldname] = value
meta = frappe.get_meta("Event Proposal")
for df in meta.fields:
if df.fieldtype == "Table" and df.fieldname not in EVENT_PROPOSAL_EXCLUDE_FIELDS:
if df.fieldname in data and isinstance(data[df.fieldname], list):
doc_data[df.fieldname] = data[df.fieldname]
frappe.get_doc(doc_data).insert(ignore_permissions=True)