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
9 changes: 9 additions & 0 deletions buzz/proposals/doctype/event_proposal/event_proposal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,14 @@ frappe.ui.form.on("Event Proposal", {
if (!frm.is_new() && frm.doc.docstatus == 0) {
frm.set_intro("Buzz Event will be created on submission of this document", "yellow");
}

if (!frm.is_new() && frm.doc.docstatus == 0 && !frm.doc.host) {
frm.add_custom_button(__("Create Host"), () => {
frm.call("create_host").then(() => {
frappe.show_alert(__("Host Created!"));
frm.refresh();
});
});
}
},
});
42 changes: 41 additions & 1 deletion buzz/proposals/doctype/event_proposal/event_proposal.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,57 @@ def before_submit(self):

self.create_event()

@frappe.whitelist()
def create_host(self):
self.check_permission("write")

if self.host:
frappe.throw(_("A Host is already linked to this proposal."))

self._create_host()
self.save()
return self.host

def _create_host(self):
if not self.host_company:
frappe.throw(_("Please enter the Company Name before creating a Host."))

if frappe.db.exists("Event Host", self.host_company):
host = frappe.get_doc("Event Host", self.host_company)
updated = False
if self.host_company_logo and not host.logo:
host.logo = self.host_company_logo
updated = True
if self.about_the_company and not host.about:
host.about = self.about_the_company
updated = True
if updated:
host.save(ignore_permissions=True)
else:
host = frappe.new_doc("Event Host")
host.name = self.host_company
host.logo = self.host_company_logo
host.about = self.about_the_company
host.insert(ignore_permissions=True)

self.host = host.name

def create_event(self):
if self.status == "Rejected":
return

if not self.host:
frappe.throw(_("Please create or set a Host before submitting the proposal."))
if not self.host_company:
frappe.throw(_("Please set a Host (or enter a Company Name) before submitting."))
self._create_host()

buzz_event = get_mapped_doc(
"Event Proposal", self.name, {"Event Proposal": {"doctype": "Buzz Event"}}
)
buzz_event.proposal = self.name
# host may have just been auto-created in-memory and is not yet persisted,
# so the mapped doc (read from DB) would miss it.
buzz_event.host = self.host
buzz_event.insert()

self.status = "Event Created"
Expand Down
116 changes: 114 additions & 2 deletions buzz/proposals/doctype/event_proposal/test_event_proposal.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (c) 2025, BWH Studios and Contributors
# See license.txt

# import frappe
import frappe
from frappe.tests import IntegrationTestCase

# On IntegrationTestCase, the doctype test records and all
Expand All @@ -17,4 +17,116 @@ class IntegrationTestEventProposal(IntegrationTestCase):
Use this class for testing interactions between multiple components.
"""

pass
@classmethod
def setUpClass(cls):
super().setUpClass()
if not frappe.db.exists("Event Category", "Test Proposal Category"):
category = frappe.new_doc("Event Category")
category.name = "Test Proposal Category"
category.insert(ignore_permissions=True)
cls.category = "Test Proposal Category"

def make_proposal(self, **kwargs):
proposal = frappe.new_doc("Event Proposal")
proposal.update(
{
"title": f"Proposal {frappe.generate_hash(length=6)}",
"category": self.category,
"medium": "Online",
"start_date": "2030-01-01",
"start_time": "10:00:00",
"end_time": "18:00:00",
"about": "<p>About the event</p>",
}
)
proposal.update(kwargs)
proposal.insert(ignore_permissions=True)
return proposal

def test_create_host_creates_and_links_event_host(self):
company = f"Acme {frappe.generate_hash(length=6)}"
proposal = self.make_proposal(host_company=company, about_the_company="We host events.")

host_name = proposal.create_host()

self.assertEqual(host_name, company)
self.assertEqual(proposal.host, company)
self.assertTrue(frappe.db.exists("Event Host", company))
self.assertEqual(frappe.db.get_value("Event Host", company, "about"), "We host events.")

def test_create_host_reuses_existing_host(self):
company = f"Existing {frappe.generate_hash(length=6)}"
existing = frappe.new_doc("Event Host")
existing.name = company
existing.insert(ignore_permissions=True)

proposal = self.make_proposal(host_company=company)
proposal.create_host()

self.assertEqual(proposal.host, company)

def test_reuse_fills_only_empty_host_fields(self):
# Existing host with empty logo/about -> proposal values fill them in.
company = f"Empty {frappe.generate_hash(length=6)}"
frappe.get_doc({"doctype": "Event Host", "__newname": company}).insert(ignore_permissions=True)

proposal = self.make_proposal(
host_company=company,
host_company_logo="/files/proposal-logo.png",
about_the_company="Proposal about.",
)
proposal.create_host()

host = frappe.get_doc("Event Host", company)
self.assertEqual(host.logo, "/files/proposal-logo.png")
self.assertEqual(host.about, "Proposal about.")

def test_reuse_does_not_overwrite_populated_host_fields(self):
# Existing host already has logo/about -> proposal must not clobber them.
company = f"Populated {frappe.generate_hash(length=6)}"
frappe.get_doc(
{
"doctype": "Event Host",
"__newname": company,
"logo": "/files/original-logo.png",
"about": "Original about.",
}
).insert(ignore_permissions=True)

proposal = self.make_proposal(
host_company=company,
host_company_logo="/files/proposal-logo.png",
about_the_company="Proposal about.",
)
proposal.create_host()

host = frappe.get_doc("Event Host", company)
self.assertEqual(host.logo, "/files/original-logo.png")
self.assertEqual(host.about, "Original about.")

def test_create_host_requires_company_name(self):
proposal = self.make_proposal()
with self.assertRaises(frappe.ValidationError):
proposal.create_host()

def test_create_host_throws_if_already_linked(self):
company = f"Acme {frappe.generate_hash(length=6)}"
proposal = self.make_proposal(host_company=company)
proposal.create_host()
with self.assertRaises(frappe.ValidationError):
proposal.create_host()

def test_submit_auto_creates_host_from_company(self):
company = f"Auto {frappe.generate_hash(length=6)}"
proposal = self.make_proposal(host_company=company, status="Approved")

proposal.submit()

self.assertEqual(proposal.host, company)
self.assertTrue(frappe.db.exists("Event Host", company))
self.assertEqual(proposal.status, "Event Created")

def test_submit_without_host_or_company_throws(self):
proposal = self.make_proposal(status="Approved")
with self.assertRaises(frappe.ValidationError):
proposal.submit()
Loading