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
8 changes: 8 additions & 0 deletions buzz/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ def process_booking(
payment_proof: str | None = None,
is_offline: bool = False,
offline_payment_method: str | None = None,
invoice_requested: bool = False,
tax_id: str | None = None,
billing_address: str | None = None,
) -> dict:
event_doc = frappe.get_cached_doc("Buzz Event", event)
if not event_doc.is_published:
Expand Down Expand Up @@ -378,6 +381,11 @@ def process_booking(
booking.coupon_code = coupon_code
booking.user = booking_user

if event_doc.apply_tax and invoice_requested:
booking.invoice_requested = 1
booking.tax_id = tax_id
booking.billing_address = billing_address

if utm_parameters:
for utm_param in utm_parameters:
booking.append(
Expand Down
35 changes: 34 additions & 1 deletion buzz/ticketing/doctype/event_booking/event_booking.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
"currency",
"coupon_code",
"discount_amount",
"billing_details_section",
"invoice_requested",
"tax_id",
"column_break_billing",
"billing_address",
"section_break_sdfp",
"amended_from",
"marketing_tab",
Expand Down Expand Up @@ -176,6 +181,28 @@
"options": "currency",
"read_only": 1
},
{
"fieldname": "billing_details_section",
"fieldtype": "Section Break",
"label": "Billing Details"
},
{
"depends_on": "eval:doc.invoice_requested==1",
"fieldname": "tax_id",
"fieldtype": "Data",
"label": "Tax ID"
},
{
"fieldname": "column_break_billing",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:doc.invoice_requested==1",
"fieldname": "billing_address",
"fieldtype": "Small Text",
"label": "Billing Address",
"mandatory_depends_on": "eval:doc.invoice_requested==1"
},
{
"fieldname": "section_break_status",
"fieldtype": "Section Break",
Expand Down Expand Up @@ -224,6 +251,12 @@
"fieldtype": "Data",
"label": "Offline Payment Method",
"read_only": 1
},
{
"default": "0",
"fieldname": "invoice_requested",
"fieldtype": "Check",
"label": "Invoice Requested"
}
],
"grid_page_length": 50,
Expand All @@ -239,7 +272,7 @@
"link_fieldname": "reference_docname"
}
],
"modified": "2026-02-05 09:10:22.542973",
"modified": "2026-05-03 07:18:23.131237",
"modified_by": "Administrator",
"module": "Ticketing",
"name": "Event Booking",
Expand Down
5 changes: 5 additions & 0 deletions buzz/ticketing/doctype/event_booking/event_booking.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,20 @@ class EventBooking(Document):
additional_fields: DF.Table[AdditionalField]
amended_from: DF.Link | None
attendees: DF.Table[EventBookingAttendee]
billing_address: DF.SmallText | None
coupon_code: DF.Link | None
currency: DF.Link
discount_amount: DF.Currency
event: DF.Link
invoice_requested: DF.Check
naming_series: DF.Literal["B.###"]
net_amount: DF.Currency
offline_payment_method: DF.Data | None
payment_method: DF.Data | None
payment_status: DF.Literal["Unpaid", "Paid", "Verification Pending"]
status: DF.Literal["Confirmed", "Approval Pending", "Approved", "Rejected"]
tax_amount: DF.Currency
tax_id: DF.Data | None
tax_label: DF.Data | None
tax_percentage: DF.Percent
total_amount: DF.Currency
Expand Down
1 change: 1 addition & 0 deletions dashboard/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare module 'vue' {
AttendeeFormControl: typeof import('./src/components/AttendeeFormControl.vue')['default']
BackButton: typeof import('./src/components/common/BackButton.vue')['default']
BaseCustomEventForm: typeof import('./src/components/BaseCustomEventForm.vue')['default']
BillingDetails: typeof import('./src/components/BillingDetails.vue')['default']
BookingEventInfo: typeof import('./src/components/BookingEventInfo.vue')['default']
BookingFinancialSummary: typeof import('./src/components/BookingFinancialSummary.vue')['default']
BookingForm: typeof import('./src/components/BookingForm.vue')['default']
Expand Down
67 changes: 67 additions & 0 deletions dashboard/src/components/BillingDetails.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<div
class="bg-surface-white border border-outline-gray-3 rounded-xl p-4 md:p-6 mb-6 shadow-sm"
>
<h3 class="text-base font-medium text-ink-gray-8 border-b pb-2 mb-4">
{{ __("Billing Details") }}
</h3>
<div class="flex flex-col gap-4">
<FormControl
type="checkbox"
:model-value="invoiceRequested"
@update:model-value="$emit('update:invoiceRequested', $event)"
:label="__('Do you need an invoice?')"
/>
<template v-if="invoiceRequested">
<FormControl
:model-value="taxId"
@update:model-value="$emit('update:taxId', $event)"
type="text"
:label="taxIdLabel"
:placeholder="__('Enter {0}', [taxIdLabel])"
/>
<div class="space-y-1.5">
<label class="text-xs text-ink-gray-5 block">
{{ __("Billing Address") }}
<span class="text-ink-red-4">*</span>
</label>
<Textarea
:model-value="billingAddress"
@update:model-value="$emit('update:billingAddress', $event)"
:placeholder="__('Enter billing address')"
:required="true"
variant="outline"
/>
</div>
Comment thread
Rl0007 marked this conversation as resolved.
</template>
</div>
</div>
</template>

<script setup>
import { computed } from "vue";
import { FormControl, Textarea } from "frappe-ui";

const props = defineProps({
invoiceRequested: {
type: Boolean,
default: false,
},
taxId: {
type: String,
default: "",
},
billingAddress: {
type: String,
default: "",
},
taxLabel: {
type: String,
default: "Tax",
Comment thread
Rl0007 marked this conversation as resolved.
},
});

defineEmits(["update:invoiceRequested", "update:taxId", "update:billingAddress"]);

const taxIdLabel = computed(() => __(props.taxLabel));
</script>
15 changes: 15 additions & 0 deletions dashboard/src/components/BookingForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@
/>
</div>

<BillingDetails
v-if="shouldApplyTax"
v-model:invoice-requested="invoiceRequested"
v-model:tax-id="taxId"
v-model:billing-address="billingAddress"
:tax-label="taxLabel"
/>

<AttendeeFormControl
v-for="(attendee, index) in attendees"
:key="attendee.id"
Expand Down Expand Up @@ -401,6 +409,7 @@ import { useLoginDialog } from "@/composables/useLoginDialog";
import { userResource } from "@/data/user";
import { formatCurrency, formatPriceOrFree } from "@/utils/currency";
import { clearBookingCache } from "@/utils/index";
import BillingDetails from "@/components/BillingDetails.vue";
import { FormControl, createResource, toast } from "frappe-ui";
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
Expand Down Expand Up @@ -488,6 +497,9 @@ const {
guestLastName,
guestEmail,
guestPhone,
invoiceRequested,
taxId,
billingAddress,
} = useBookingFormStorage(props.eventRoute);

const guestFullName = computed(() => `${guestFirstName.value} ${guestLastName.value}`.trim());
Expand Down Expand Up @@ -1170,6 +1182,9 @@ async function submit() {
guest_email: props.isGuestMode ? guestEmail.value.trim() : null,
guest_full_name: props.isGuestMode ? guestFullName.value.trim() : null,
guest_phone: props.isGuestMode && isPhoneOtp.value ? guestPhone.value.trim() : null,
invoice_requested: invoiceRequested.value,
tax_id: invoiceRequested.value ? taxId.value?.trim() : null,
billing_address: invoiceRequested.value ? billingAddress.value?.trim() : null,
};

if (props.isGuestMode) {
Expand Down
10 changes: 10 additions & 0 deletions dashboard/src/composables/useBookingFormStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export function useBookingFormStorage(eventRoute: string) {
const guestEmail = useStorage(`${storageKeyPrefix}-guest-email`, "")
const guestPhone = useStorage(`${storageKeyPrefix}-guest-phone`, "")

const invoiceRequested = useStorage(`${storageKeyPrefix}-invoice-requested`, false)
const taxId = useStorage(`${storageKeyPrefix}-tax-id`, "")
const billingAddress = useStorage(`${storageKeyPrefix}-billing-address`, "")

/**
* Clear all stored booking form data
* This should be called when payment is successful
Expand All @@ -38,6 +42,9 @@ export function useBookingFormStorage(eventRoute: string) {
guestLastName.value = ""
guestEmail.value = ""
guestPhone.value = ""
invoiceRequested.value = false
taxId.value = ""
billingAddress.value = ""
}

/**
Expand All @@ -58,6 +65,9 @@ export function useBookingFormStorage(eventRoute: string) {
guestLastName,
guestEmail,
guestPhone,
invoiceRequested,
taxId,
billingAddress,
clearStoredData,
hasStoredData,
}
Expand Down
Loading