Initialize fork and rebrand app to event_manager
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user