Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 58 additions & 12 deletions buzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,43 @@ def get_event_booking_data(event_route: str) -> dict:

data.event_details = event_doc

# Custom Fields
custom_fields = frappe.db.get_all(
"Buzz Custom Field", filters={"event": event_doc.name, "enabled": 1}, fields=["*"]
)
data.custom_fields = custom_fields

return data


@frappe.whitelist()
def process_booking(attendees: list[dict], event: str) -> dict:
def process_booking(attendees: list[dict], event: str, booking_custom_fields: dict | None = None) -> dict:
booking = frappe.new_doc("Event Booking")
booking.event = event
booking.user = frappe.session.user

# Add booking-level custom fields
if booking_custom_fields:
# Get custom field definitions for this event to get proper labels and types
booking_custom_field_defs = frappe.db.get_all(
"Buzz Custom Field",
filters={"event": event, "enabled": 1, "applied_to": "Booking"},
fields=["fieldname", "label", "fieldtype"],
)
custom_field_map = {cf["fieldname"]: cf for cf in booking_custom_field_defs}

for field_name, field_value in booking_custom_fields.items():
if field_value and field_name in custom_field_map: # Only add non-empty values and valid fields
field_def = custom_field_map[field_name]
booking.append(
"additional_fields",
{
"fieldname": field_name,
"value": str(field_value),
"label": field_def["label"],
"fieldtype": field_def["fieldtype"],
},
)
for attendee in attendees:
add_ons = attendee.get("add_ons", None)
if add_ons:
Expand All @@ -161,15 +190,17 @@ def process_booking(attendees: list[dict], event: str) -> dict:
add_ons=add_ons,
)

booking.append(
"attendees",
{
"full_name": attendee.get("full_name"),
"email": attendee.get("email"),
"ticket_type": attendee.get("ticket_type"),
"add_ons": add_ons.name if add_ons else None,
},
)
# Process custom fields for this attendee
custom_fields = attendee.get("custom_fields", {})
attendee_row = {
"full_name": attendee.get("full_name"),
"email": attendee.get("email"),
"ticket_type": attendee.get("ticket_type"),
"add_ons": add_ons.name if add_ons else None,
"custom_fields": custom_fields if custom_fields else None,
}

booking.append("attendees", attendee_row)

booking.insert(ignore_permissions=True)
frappe.db.commit()
Expand Down Expand Up @@ -315,7 +346,14 @@ def get_booking_details(booking_id: str) -> dict:
add_ons = frappe.db.get_all(
"Ticket Add-on Value",
filters={"parent": ("in", (ticket.name for ticket in tickets))},
fields=["parent", "name", "add_on", "value", "add_on.title as add_on_title", "add_on.user_selects_option as user_selects_option"],
fields=[
"parent",
"name",
"add_on",
"value",
"add_on.title as add_on_title",
"add_on.user_selects_option as user_selects_option",
],
)

# Get available options for add-ons
Expand Down Expand Up @@ -569,7 +607,15 @@ def get_ticket_details(ticket_id: str) -> dict:
add_ons = frappe.db.get_all(
"Ticket Add-on Value",
filters={"parent": ticket_id},
fields=["name", "add_on", "add_on.title as add_on_title", "value", "price", "currency", "add_on.user_selects_option as user_selects_option"],
fields=[
"name",
"add_on",
"add_on.title as add_on_title",
"value",
"price",
"currency",
"add_on.user_selects_option as user_selects_option",
],
)

# Get available options for add-ons (for preference management)
Expand Down
Empty file added buzz/buzz/doctype/__init__.py
Empty file.
Empty file.
8 changes: 8 additions & 0 deletions buzz/buzz/doctype/buzz_custom_field/buzz_custom_field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) 2025, BWH Studios and contributors
// For license information, please see license.txt

// frappe.ui.form.on("Buzz Custom Field", {
// refresh(frm) {

// },
// });
112 changes: 112 additions & 0 deletions buzz/buzz/doctype/buzz_custom_field/buzz_custom_field.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-11-01 11:29:38.327158",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"enabled",
"event",
"label",
"fieldname",
"mandatory",
"placeholder",
"column_break_fpgn",
"applied_to",
"fieldtype",
"options"
],
"fields": [
{
"fieldname": "event",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Event",
"options": "Buzz Event",
"reqd": 1
},
{
"fieldname": "column_break_fpgn",
"fieldtype": "Column Break"
},
{
"default": "Booking",
"fieldname": "applied_to",
"fieldtype": "Select",
"label": "Applied To",
"options": "Booking\nTicket"
},
{
"fieldname": "label",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Label",
"reqd": 1
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"label": "Name"
},
{
"default": "Data",
"fieldname": "fieldtype",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Type",
"options": "Data\nPhone\nEmail\nSelect",
"reqd": 1
},
{
"fieldname": "options",
"fieldtype": "Small Text",
"label": "Options"
},
{
"default": "1",
"fieldname": "enabled",
"fieldtype": "Check",
"label": "Enabled?"
},
{
"default": "0",
"fieldname": "mandatory",
"fieldtype": "Check",
"label": "Mandatory?"
},
{
"fieldname": "placeholder",
"fieldtype": "Data",
"label": "Placeholder"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-11-01 12:56:21.483252",
"modified_by": "Administrator",
"module": "Buzz",
"name": "Buzz Custom Field",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "label"
}
28 changes: 28 additions & 0 deletions buzz/buzz/doctype/buzz_custom_field/buzz_custom_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) 2025, BWH Studios and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class BuzzCustomField(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from frappe.types import DF

applied_to: DF.Literal["Booking", "Ticket"]
enabled: DF.Check
event: DF.Link
fieldname: DF.Data | None
fieldtype: DF.Literal["Data", "Phone", "Email", "Select"]
label: DF.Data
mandatory: DF.Check
options: DF.SmallText | None
placeholder: DF.Data | None
# end: auto-generated types

pass
20 changes: 20 additions & 0 deletions buzz/buzz/doctype/buzz_custom_field/test_buzz_custom_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2025, BWH Studios and Contributors
# See license.txt

# import frappe
from frappe.tests import IntegrationTestCase

# On IntegrationTestCase, the doctype test records and all
# link-field test record dependencies are recursively loaded
# Use these module variables to add/remove to/from that list
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]


class IntegrationTestBuzzCustomField(IntegrationTestCase):
"""
Integration tests for BuzzCustomField.
Use this class for testing interactions between multiple components.
"""

pass
7 changes: 6 additions & 1 deletion buzz/events/doctype/buzz_event/buzz_event.json
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,14 @@
"group": "General",
"link_doctype": "Additional Event Page",
"link_fieldname": "event"
},
{
"group": "Customisations",
"link_doctype": "Buzz Custom Field",
"link_fieldname": "event"
}
],
"modified": "2025-10-29 17:22:01.221301",
"modified": "2025-11-01 12:04:09.030132",
"modified_by": "Administrator",
"module": "Events",
"name": "Buzz Event",
Expand Down
Empty file.
61 changes: 61 additions & 0 deletions buzz/ticketing/doctype/additional_field/additional_field.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-11-01 11:36:52.321319",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"label",
"fieldname",
"column_break_nptw",
"value",
"fieldtype"
],
"fields": [
{
"fieldname": "label",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Label"
},
{
"fieldname": "fieldname",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Fieldname",
"reqd": 1
},
{
"fieldname": "value",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Value",
"reqd": 1
},
{
"fieldname": "column_break_nptw",
"fieldtype": "Column Break"
},
{
"fieldname": "fieldtype",
"fieldtype": "Data",
"label": "Fieldtype"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2025-11-01 11:38:22.581796",
"modified_by": "Administrator",
"module": "Ticketing",
"name": "Additional Field",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
26 changes: 26 additions & 0 deletions buzz/ticketing/doctype/additional_field/additional_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2025, BWH Studios and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class AdditionalField(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from frappe.types import DF

fieldname: DF.Data
fieldtype: DF.Data | None
label: DF.Data | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
value: DF.Data
# end: auto-generated types

pass
Loading