<template>
<div>
<div class="modal modal-mask modal-mask-checkout" v-if="openModal">
<div class="modal-dialog modal-container modal-checkout">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" @click="step === 2 ? previousStep() : close()">
<i class="fa fa-chevron-left"></i>
</button>
<div class="text-left inline-block">
<h3 class="title ticket-selected-text">{{ event.title }}</h3>
</div>
<div class="text-right float-right">
<h3 class="title ticket-selected-text date">{{ changeDateFormat(this.booking_date, 'dddd LLL') }} {{ changeTimeFormat(this.start_time, 'hh:mm A') }}</h3>
</div>
</div>
<div class="container" v-html="form_payment_response"></div>
<div v-show="selecting_seat && !is_virtual_event">
<iframe
:src="src_ticket"
frame-id="my-ifram"
class="ticket-border"
name="my-frame"
width="100%"
height="85%"
/>
<div class="col-lg-1 col-xs-12 pull-right">
<button @click="checkout();" class="lgx-btn lgx-btn-red btn btn-block green-btn">{{ trans('em.checkout') }}</button>
</div>
</div>
<form v-show="!selecting_seat" ref="form" @submit.prevent="validateForm" method="POST" >
<!-- CUSTOM -->
<div class="form-group pl-3" v-if="is_admin > 0">
<input type="checkbox" class="custom-control-input" :value=1 name="is_bulk" v-model="is_bulk" >
<label class="custom-control-label" >{{ trans('em.complimentary_bookings') }}</label>
</div>
<!-- CUSTOM -->
<input type="hidden" class="form-control" name="event_id" :value="event.event_id" >
<input type="hidden" class="form-control" name="booking_date" :value="serverTimezone(booking_date+' '+start_time, 'dddd LL HH:mm a').format('YYYY-MM-DD')" >
<input type="hidden" class="form-control" name="booking_end_date"
:value="(booking_end_date != null && typeof(booking_end_date) != 'undefined') ?
serverTimezone(booking_end_date+' '+end_time, 'dddd LL HH:mm a').format('YYYY-MM-DD') : null"
>
<input type="hidden" class="form-control" name="start_time" :value="serverTimezone(booking_date+' '+start_time, 'dddd LL HH:mm a').format('HH:mm:ss')" >
<input type="hidden" class="form-control" name="end_time" :value="serverTimezone((booking_end_date == null ? booking_date : booking_end_date) +' '+end_time, 'dddd LL HH:mm a').format('HH:mm:ss')" >
<input type="hidden" class="form-control" name="merge_schedule" :value="event.merge_schedule" >
<!-- CUSTOM -->
<div class="row" v-if="is_twilio > 0">
<div class="col-md-12 mb-5" >
<input type="hidden" class="form-control" name="phone_t" v-model="phone_t" >
<div class="col-md-5" v-if="customer != null && customer.phone == null ">
<label>{{ trans('em.phone') + '('+ trans('em.required') +')' }}</label>
<input type="text" class="form-control" name="phone_t" v-model="phone_t" v-validate="'required'" :placeholder="trans('em.phone_info')">
<span v-show="errors.has('phone_t')" class="help text-danger">{{ errors.first('phone_t') }}</span>
</div>
</div>
</div>
<!-- CUSTOM -->
<div class="row">
<!-- only for admin & organizer -->
<!-- <div class="col-md-12 mb-5" v-if="is_customer <= 0"> -->
<!-- Booking Info -->
<div class="container">
<div v-if="(step === 2 && t_type === 2) || t_type === 1">
<div class="checkout_title">{{ trans('em.Event_Information') }}</div>
<table class="ui celled striped table">
<tr>
<th>{{ trans('em.Event_Name') }}</th>
<td>{{ event.title }}</td>
</tr>
<tr>
<th>{{ trans('em.Event_Date') }}</th>
<td>{{ changeDateFormat(moment(userTimezone(moment(booking_date,'dddd LL').format('YYYY-MM-DD') + ' ' + moment(start_time, 'hh:mm A').format('HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss').format('YYYY-MMM-DD'))) }} {{ changeTimeFormat(start_time) }} {{ '('+ showTimezone() +')' }} </td>
</tr>
<tr v-if="!is_virtual_event">
<th>{{ trans('em.Event_Location') }}</th>
<td>{{ event.city }}, {{ event.venue }}</td>
</tr>
</table>
</div>
<div v-if="is_virtual_event">
<input type="hidden" class="form-control" name="ticket_id[]" :value="tickets[0].id" >
<input type="hidden" class="form-control" name="ticket_title[]" :value="tickets[0].title" >
<input type="hidden" class="form-control" name="quantity[]" :value="quantity[0]" >
</div>
<div class="tc_class" v-else>
<div v-if="t_type === 1">
<div class="checkout_title">{{ trans('em.Ticket_Information') }}</div>
</div>
<div v-if="(step === 1 && t_type === 2)">
<div class="checkout_title">{{ trans('em.tickets') }}</div>
</div>
<div v-if="t_type == 1">
<!-- CUSTOM -->
<table
v-for="(item, index) in quantity"
:key = "index"
class="ticket_type_checkout ui celled striped table"
>
<tbody v-if="quantity[index] > 0">
<input type="hidden" class="form-control" name="ticket_id[]" :value="tickets[index].id" >
<input type="hidden" class="form-control" name="ticket_title[]" :value="tickets[index].title" >
<input type="hidden" class="form-control" name="quantity[]" :value="quantity[index]" >
<tr>
<th>{{ trans('em.Ticket_Type') }}</th>
<td>{{ tickets[index].title }}</td>
</tr>
<tr>
<th>{{ trans('em.Seat_Number') }}</th>
<td class="seat_number"><p v-for="(seat, index) in ticket_info[tickets[index].id]"
:key = "index">{{ seat[1] }}</p></td>
</tr>
<tr>
<th>{{ trans('em.Quantity') }}</th>
<td>{{ ticket_info[tickets[index].id] ? ticket_info[tickets[index].id].length : 0 }}</td>
</tr>
<tr>
<th>{{trans('em.Price')}}</th>
<td class="price-convert" :data-currency="currency" :data-amount="tickets[index].price"></td>
</tr>
</tbody>
</table>
</div>
<div v-else-if="t_type === 2">
<div v-if="step === 1 && step !== 2">
<div class="col-md-12 nopm">
<ul class="list-group m-0">
<li class="list-group-item justify-content-between lh-condensed d-flex-wrap nopm"
v-for="(item, index) in tickets"
:key = "index"
>
<ul class="list-group m-0 list-group-flush">
<li class="list-group-item d-flex justify-content-between lh-condensed d-flex-wrap plr-none">
<input type="hidden" class="form-control" name="ticket_id[]" :value="item.id" >
<input type="hidden" class="form-control" name="ticket_title[]" :value="item.title" >
<div class="w-50">
<h6 class="my-0 item_title">{{ item.title }}</h6>
</div>
<div v-if="item.t_soldout > 0" class="w-10 w-20-mobile">
<p class="text-danger"><small><i class="fas fa-times-circle"></i> {{ trans('em.t_soldout') }}</small></p>
</div>
<div class="w-10 text-right item-price" v-if="item.t_soldout <= 0">
{{item.price}}
</div>
<div v-show="item.t_soldout <= 0" class="w-30 w-20-mobile">
<div v-if="item.seatchart != null && item.seatchart.status > 0 && is_bulk <= 0">
<p>{{ trans('em.quantity') }}: {{ quantity[index] }}</p>
</div>
<div v-if="is_bulk > 0 ">
<div v-if='typeof(booked_tickets[item.id+"-"+booked_date_server]) != "undefined"
'>
<input type="number" name="quantity[]"
v-model="quantity[index]" value="0" class="form-control form-input-sm"
min="0"
>
<!-- Show if vacant less than max_ticket_qty -->
<p class="text-info"
v-if="booked_tickets[item.id+'-'+booked_date_server].total_vacant < max_ticket_qty && booked_tickets[item.id+'-'+booked_date_server].total_vacant > 0">
<small><i class="fas fa-exclamation"></i> {{ trans('em.vacant') }}
{{ booked_tickets[item.id+'-'+booked_date_server].total_vacant }}</small>
</p>
<p class="text-danger"
v-if="booked_tickets[item.id+'-'+booked_date_server].total_vacant < max_ticket_qty && booked_tickets[item.id+'-'+booked_date_server].total_vacant <= 0">
<small><i class="fas fa-times-circle"></i> {{ trans('em.vacant') }} 0</small>
</p>
</div>
<div v-else>
<input type="number" name="quantity[]" v-model="quantity[index]" value="0" class="form-control form-input-sm" min="0" >
<!-- Show if vacant less than max_ticket_qty -->
<p class="text-info"
v-if="item.quantity < max_ticket_qty && item.quantity > 0">
<small><i class="fas fa-exclamation"></i> {{ trans('em.vacant') }}
{{ item.quantity }}</small>
</p>
<p class="text-danger"
v-if="item.quantity <= 0">
<small><i class="fas fa-times-circle"></i> {{ trans('em.vacant') }} 0</small>
</p>
</div>
</div>
<div class="custom" :class="{'no-display': (item.seatchart != null && item.seatchart.status > 0)}">
<div class="custom-dropdown" v-click-outside="closeDropdown">
<div
class="custom-dropdown-selected"
:class="{ 'clicked': dropdownVisible[index] }"
@click="toggleDropdown(index)"
>
{{ displayText[index] || trans('em.Number_of_tickets') }}
</div>
<div class="custom-dropdown-options" :class="{ 'show': dropdownVisible[index] }">
<div
class="custom-dropdown-option"
:class="{ 'selected': quantity[index] === null }"
@click="selectOption(index, null)"
>
{{ trans('em.Number_of_tickets') }}
</div>
<div
class="custom-dropdown-option"
:class="{ 'selected': itm === quantity[index] }"
v-for="(itm, ind) in item.quantity > max_ticket_qty ? parseInt(max_ticket_qty) : parseInt(item.quantity)"
:key="ind"
@click="selectOption(index, itm)"
>
{{ itm }}
</div>
</div>
</div>
<p
class="text-info"
v-if="item.quantity < max_ticket_qty && item.quantity > 0"
>
<small><i class="fas fa-exclamation"></i> {{ trans('em.vacant') }}
{{ item.quantity }}</small>
</p>
<p class="text-danger" v-if="item.quantity <= 0">
<small><i class="fas fa-times-circle"></i> {{ trans('em.vacant') }} 0</small>
</p>
</div>
</div>
<div class="break-flex">
<p class="ticket-info" v-if="ticket_info[index]">{{ item.description }}</p>
<div class="ui horizontal divider">
<a
class="pointer ticket-info-toggle"
@click="toggleTicketInfo(index)"
>
<small v-if="ticket_info[index]">{{ trans('em.hide_info') }} <i class="fal fa-angle-down"></i></small>
<small v-else>{{ trans('em.show_info') }} <i class="fal fa-angle-up"></i></small>
</a>
</div>
</div>
<!-- *** CUSTOM *** start-->
<div style="overflow: auto;" class="break-flex" v-if="item.seatchart != null && item.seatchart.status > 0 && is_bulk <= 0 && item.t_soldout <= 0">
<seat-component :ticket="item" :ticket_index="index" :max_ticket_qty="max_ticket_qty" :quantity="quantity[index]" :event="event"></seat-component>
</div>
<div class="break-flex" v-show="item.promocodes && item.promocodes.length > 0">
<div class="input-group mt-5" v-show="item.price > 0 && item.t_soldout <= 0 && is_bulk <= 0">
<input type="text" name="promocode[]" class="form-control form-input-sm" :placeholder="trans('em.enter_promocode')"
v-model="promocode[index]"
:id="'pc_'+index"
>
<span class="input-group-btn">
<button class="btn lgx-btn lgx-btn-sm lgx-btn-success" type="button"
@click="pc_readonly[index] > 0 ? '' : applyPromocode(item.id, index)"
:id="'pcb_'+index"
>
{{ trans('em.apply') }}
</button>
</span>
</div>
<span class="text-success" :id="'pc_success_'+index"></span>
<span class="text-danger" :id="'pc_error_'+index"></span>
</div>
<!-- *** CUSTOM *** end-->
<!-- CUSTOM -->
</li>
</ul>
<!-- CUSTOM -->
</li>
</ul>
</div>
</div>
<!-- END LIST TICKET -->
</div>
</div>
<div class="checkout_title pt-20">{{ trans('em.Price_Information') }}</div>
<table class="ui celled striped table">
<tr>
<th>{{ trans('em.Total_Tickets_Price') }}</th>
<td class="price-convert" :data-currency="currency" :data-amount="totalExcludeTax()"></td>
</tr>
<tr>
<th>{{ trans('em.VAT') }}</th>
<td class="price-convert" :data-currency="currency" :data-amount="total_tax.reduce((a, b) => a+b, 0)"></td>
</tr>
<tr>
<th>{{ trans('em.Total_Price') }}</th>
<td class="price-convert" :data-currency="currency" :data-amount="total"></td>
</tr>
</table>
<div v-if="step === 1 && t_type === 2 && showNextButton">
<div class="col-md-2 col-sm-6 pull-right nopm">
<button @click="nextStep" class="lgx-btn lgx-btn-red btn btn-block green-btn">{{ trans('em.checkout') }}</button>
</div>
</div>
<div v-if="(step === 2 && t_type === 2) || t_type === 1">
<form class="coupon_form" ref="form_coupon" @submit.prevent="validateFormCoupon" method="POST">
<div class="ui action input">
<input type="text" name="coupon" :placeholder="trans('em.Coupon_Code')" required>
<button class="ui button" type="submit" :class="{ 'disabled' : disable }" :disabled="disable">{{ trans('em.apply') }}</button>
</div>
</form>
<div v-if="num_coupon > 0" :data-num-coupon="num_coupon">
<div class="checkout_title">{{ trans('em.Your_Guests_Details') }}</div>
<p>{{ trans('em.please_enter_your_guests_name') }}</p>
<div v-for="index in parseInt(num_coupon)" :key="index" :data-index="index" class="ui two column grid">
<div class="column">
<div class="ui input">
<input type="text" :placeholder="trans('em.Name_frind_gift')" class="custom-control-input" :name="`name_${index}`">
</div>
</div>
<div class="column">
<div class="ui input">
<input type="text" :placeholder="trans('em.Email_frind_gift')" class="custom-control-input" :name="`email_${index}`">
</div>
</div>
</div>
</div>
<div class="ui horizontal divider">{{ trans('em.Payment_method') }}</div>
<p>{{ trans('em.Please_select_a_payment_method') }}</p>
<!-- If not logged in -->
<div v-if="!register_user_id">
<div class="alert alert-danger">
{{ trans('em.please_login_signup') }}
</div>
</div>
<!-- Payments -->
<div v-if="bookedTicketsTotal() > 0 && register_user_id">
<!-- CUSTOM -->
<!-- Free -->
<!-- <div class="d-block my-3" v-if="total <= 0"> -->
<div class="d-block my-3" v-if="(parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) <= 0">
<div class="radio-inline">
<input id="free_order" name="free_order" type="radio" class="custom-control-input" checked v-model="payment_method" value="free">
<label class="custom-control-label" for="free_order"> <i class="fas fa-glass-cheers"></i> {{ trans('em.free') }} <small>({{ trans('em.rsvp') }} )</small></label>
</div>
</div>
<!-- Paid -->
<div class="d-block my-3" v-else-if="(parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0">
<!-- For Organizer & Customer -->
<div v-if="is_admin <= 0 && is_bulk <= 0" v-for="(method, index) in payment_methods" class="radio-inline">
<input type="radio" class="custom-control-input hidden-checkbox" :id="method.payment_method_slug" name="payment_method" v-model="payment_method" :value="method.payment_method_id">
<img :src="'/storage/payment/image_for_' + method.payment_method_slug + '.png'" alt="Payment Method" class="checkbox-image" @click="onSelectPaymentMethod(method); toggleCheckbox(method.payment_method_slug, method)">
</div>
<!-- CUSTOM -->
<!-- For Admin & Organizer & Customer -->
<div class="radio-inline"
v-if="(is_organiser > 0 && is_offline_payment_organizer > 0) || (is_customer > 0 && is_offline_payment_customer > 0) || (is_admin > 0) || (is_bulk > 0)">
<input type="radio" class="custom-control-input" id="payment_method_offline" name="payment_method" v-model="payment_method" value="offline">
<label class="custom-control-label" for="payment_method_offline">
<i class="fas fa-suitcase-rolling"></i> {{ trans('em.offline') }}
<small>({{ trans('em.cash_on_arrival') }})</small>
</label>
</div>
<p v-if="payment_method == 'offline'" class="text-info"><strong>{{ trans('em.offline_payment_info') }}: </strong><small v-html="event.offline_payment_info"></small></p>
<p class="text-mute" v-html="trans('em.order_terms')"></p>
</div>
</div>
<!-- CUSTOM -->
<stripe-component
ref="stripe"
v-if="payment_method == 2 && total > 0 && register_user_id && is_admin <= 0 && isStripe > 0 && (parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0"
:payment_method="payment_method" :bookings_data="bookings_data"
:stripePublishableKey="stripePublishableKey"
:stripeSecretKey="stripe_secret_key"
></stripe-component>
<authorize-net v-if="total > 0 && register_user_id && is_admin <= 0 && isAuthorizeNet > 0 && (parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0"></authorize-net>
<tpay v-if="total > 0 && register_user_id && is_admin <= 0 && isTPay > 0 && (parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0"></tpay>
<wallet v-if="total > 0 && register_user_id && is_admin <= 0 && isWallet > 0 && (parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0"></wallet>
<pay-stack ref="pay_stack" v-if="payment_method == 6 && total > 0 && register_user_id && is_admin <= 0 && is_pay_stack > 0 (parseFloat(total) - parseFloat(promocode_reward)).toFixed(2) > 0"></pay-stack>
<!-- CUSTOM -->
<div class="row">
<div class="col-md-2 col-sm-12" v-if="register_user_id">
<button :class="{ 'disabled' : disable }" :disabled="disable" type="submit" class="btn lgx-btn lgx-btn-red" ><i class="fas fa-cash-register"></i> {{ (total <= 0) ? trans('em.rsvp') : trans('em.checkout') }}</button>
</div>
<div class="col-xs-12" v-else>
</div>
</div>
</div>
</div> </div>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapMutations} from 'vuex';
import mixinsFilters from '../../../../mixins.js';
import _ from 'lodash';
// CUSTOM
import Stripe from './custom/Stripe.vue';
import RegisterUser from './custom/RegisterUser.vue';
import AuthorizeNet from './custom/AuthorizeNet.vue';
import AddAttendee from './custom/AddAttendee';
import VueCountdown from '@chenfengyuan/vue-countdown';
import AttendeeComponent from './custom/Attendee.vue';
import SeatComponent from './custom/Seat';
import PayStack from './custom/PayStack';
import TPay from './custom/TPay';
import Wallet from "./custom/Wallet";
// CUSTOM
Vue.directive("click-outside", {
bind(el, binding, vnode) {
el.clickOutsideEvent = function (event) {
if (!(el === event.target || el.contains(event.target))) {
vnode.context[binding.expression](event);
}
};
document.body.addEventListener("mouseup", el.clickOutsideEvent);
},
unbind(el) {
document.body.removeEventListener("mouseup", el.clickOutsideEvent);
},
});
export default {
components: {
// CUSTOM
'stripe-component' : Stripe,
RegisterUser,
AuthorizeNet,
AddAttendee,
VueCountdown,
AttendeeComponent,
SeatComponent,
'pay-stack' : PayStack,
'tpay': TPay,
'wallet': Wallet,
// CUSTOM
},
mixins:[
mixinsFilters
],
props : [
'tickets',
'max_ticket_qty',
'event',
'currency',
'login_user_id',
'is_admin',
'is_organiser',
'is_pos',
'is_customer',
'is_paypal',
'is_fawry',
'is_offline_payment_organizer',
'is_offline_payment_customer',
'booked_tickets',
'is_virtual_event',
'payment_methods',
'wallet',
'num_coupon',
'index',
],
data() {
return {
openModal : false,
ticket_info : [],
moment : moment,
quantity : [1],
price : null,
total_price : [],
showNextButton: false,
customer_id : 0,
total : 0,
step: 1,
displayText: [],
eventListeners: [],
total_display : '',
total_tax : [],
total_tax_display : '',
disable : false,
payment_method : 'offline',
payment_method_slug : '',
form_payment_response : '',
phone_number: '',
displayText: [],
dropdownVisible: [],
// customers options
options : [],
//selected customer
customer : null,
/* CUSTOM */
//promocode
bookings_data : null,
stripePublishableKey : stripe_publishable_key,
stripe_secret_key : stripe_secret_key,
isStripe : is_stripe,
email : '',
register_user_id : this.login_user_id,
register_modal : 0,
//promocode
promocode : [],
ticket_promocodes : [],
pc_readonly : [],
promocode_reward : 0,
// cardName : "diep",
// cardNumber : "4005550000000001",
// cardMonth : "05",
// cardYear : "2025",
// cardCvv : "123",
cardName : "",
cardNumber : "",
cardMonth : "",
cardYear : "",
cardCvv : "",
isAuthorizeNet : false,
isTPay: false,
isWallet: false,
is_bitpay : is_bitpay,
is_stripe_direct : is_stripe_direct,
add_attendee : 0,
is_twilio : is_twilio,
phone_t : '',
name : [[],[]],
phone : [[],[]],
address : [[],[]],
is_bulk : 0,
is_donation : [],
pay_stack : 0,
is_pay_stack : is_pay_stack,
/* CUSTOM */
selecting_seat: true,
src_ticket: '',
t_type: 1,
}
},
computed: {
// get global variables
...mapState( ['booking_date', 'start_time', 'end_time', 'booking_end_date', 'booked_date_server', ]),
},
methods: {
// update global variables
...mapMutations(['add', 'update']),
checkout: function() {
let url = route('events_get_booking_seat');
let post_data = new FormData();
post_data.append('event_id', this.event.event_id);
post_data.append('tickets', JSON.stringify(this.tickets) );
post_data.append('post_id', this.event.post_id);
if (this.num_coupon > 0) {
post_data.append('buy_coupon', 1);
post_data.append('num_coupon', this.num_coupon);
}
// show loader
this.showLoaderNotification(trans('em.processing'));
axios.post(url, post_data).then(res => {
Swal.close();
var quantity = res.data.quantity.reduce((a, b) => a + b, 0);
if (quantity <= 0) {
window.app.$helpers.showToast('warning', 'Please select seat');
} else {
this.selecting_seat = this.is_virtual_event ? false : !this.selecting_seat;
this.quantity = res.data.quantity;
this.ticket_info = res.data.seat;
}
}).catch(e => {
Swal.close();
console.error(url, e);
})
},
toggleTicketInfo(index) {
this.$set(this.ticket_info, index, !this.ticket_info[index]);
},
closeDropdown() {
this.dropdownVisible = this.dropdownVisible.map(() => false);
},
toggleDropdown(index) {
this.$set(this.dropdownVisible, index, !this.dropdownVisible[index]);
},
selectOption(index, value) {
if (value === null) {
value = 0;
}
this.$set(this.quantity, index, value);
this.$set(
this.displayText,
index,
value === 0
? null
: `${this.trans('em.Edit_selection')} (${value})`
);
this.$set(this.dropdownVisible, index, false);
},
nextStep() {
this.step += 1;
},
previousStep() {
this.step -= 1;
},
getLinkSeatChartThenOpen: function() {
let url = route('events_get_link_seat_chart');
let post_data = new FormData();
post_data.append('event_id', this.event.event_id);
post_data.append('post_id', this.event.post_id);
post_data.append('start_date', moment(moment(this.booking_date,'dddd LL').format('YYYY-MM-DD') + ' ' + moment(this.start_time, 'hh:mm A').format('HH:mm:ss'), 'YYYY-MM-DD HH:mm:ss').locale('en').format('YYYY-MM-DD'));
post_data.append('start_time', moment(this.start_time, 'hh:mm A').locale('en').format('HH:mm:ss'));
// show loader
this.showLoaderNotification(trans('em.processing'));
axios.post(url, post_data).then(res => {
this.src_ticket = res.data.src_ticket;
this.selecting_seat = true;
Swal.close();
}).catch(e => {
Swal.close();
console.error(url, e);
})
},
// reset form and close modal
close: function () {
this.price = null;
this.quantity = [];
this.total_price = [];
this.add({
booking_date : null,
booked_date_server : null,
booking_end_date : null,
start_time : null,
end_time : null,
})
this.openModal = false;
},
toggleCheckbox(id, method) {
const checkbox = document.getElementById(id);
const allCheckboxes = document.getElementsByName(checkbox.name);
// Deselect all radio buttons
allCheckboxes.forEach(input => {
const img = input.nextElementSibling;
img.classList.remove('selected');
});
// Select the clicked radio button
checkbox.checked = true;
const image = checkbox.nextElementSibling;
image.classList.add('selected');
// Update the payment_method model value
this.payment_method = method.payment_method_id;
// Trigger the change event for the checkbox
checkbox.dispatchEvent(new Event('change'));
},
onSelectPaymentMethod(method) {
this.isAuthorizeNet = 0;
this.isTPay = 0;
this.isWallet = 0;
if (method.payment_method_slug == 'payfort') {
this.isAuthorizeNet = 1;
} else if (method.payment_method_slug == 'tpay') {
this.isTPay = 1;
} else if (method.payment_method_slug == 'wallet') {
this.isWallet = 1;
}
},
bookTickets(){
// show loader
// this.showLoaderNotification(trans('em.processing'));
// prepare form data for post request
// this.disable = true;
let post_url = route('eventmie.bookings_book_tickets');
let post_data = new FormData(this.$refs.form);
post_data.append("device_fingerprint", document.getElementById('device_fingerprint').value);
//CUSTOM
if (this.num_coupon > 0) {
post_data.append('buy_coupon', 1);
post_data.append('num_coupon', this.num_coupon);
}
/* CUSTOM */
// in case of Stripe
// if(this.payment_method == 2 && this.total > 0) {
// this.stripePayment(post_data);
// } else if(this.payment_method == 6 && this.total > 0){
// this.PayStack(post_data);
// } else {
/* CUSTOM */
// axios post request
axios.post(post_url, post_data)
.then(res => {
if(res.data.status && res.data.message != '' && typeof(res.data.message) != "undefined") {
// hide loader
Swal.hideLoading();
// close popup
this.close();
this.showNotification('success', res.data.message);
}
else if(!res.data.status && res.data.message != '' && res.data.url != '' && typeof(res.data.url) != "undefined"){
// hide loader
Swal.hideLoading();
// close popup
this.close();
this.showNotification('error', res.data.message);
setTimeout(() => {
window.location.href = res.data.url;
}, 1000);
}
if(res.data.url != '' && res.data.status && typeof(res.data.url) != "undefined") {
// hide loader
Swal.hideLoading();
setTimeout(() => {
window.location.href = res.data.url;
}, 1000);
}
if(res.data.form != '' && res.data.status && typeof(res.data.form) != "undefined") {
// hide loader
Swal.hideLoading();
this.form_payment_response = res.data.form;
setTimeout(() => {
document.getElementById('form-payfort-tokenization').submit();
}, 1000);
}
if(!res.data.status && res.data.message != '' && typeof(res.data.message) != "undefined") {
// hide loader
Swal.hideLoading();
// close popup
this.close();
this.showNotification('error', res.data.message);
}
})
.catch(error => {
this.disable = false;
let serrors = Vue.helpers.axiosErrors(error);
if (serrors.length) {
this.serverValidate(serrors);
}
});
// }
},
applyCoupon() {
// show loader
// this.showLoaderNotification(trans('em.processing'));
// prepare form data for post request
// this.disable = true;
let post_url = route('eventmie.bookings_apply_coupon');
let post_data = new FormData(this.$refs.form_coupon);
post_data.append("event_id", this.event.event_id);
axios.post(post_url, post_data)
.then(res => {
this.disable = false;
})
.catch(error => {
this.disable = false;
let serrors = Vue.helpers.axiosErrors(error);
if (serrors.length) {
this.serverValidate(serrors);
}
});
// }
},
// validate data on form submit
validateForm(e) {
this.$validator.validateAll().then((result) => {
if (result) {
this.disable = true;
// this.formSubmit(e);
//CUSTOM
this.bookTickets();
//CUSTOM
}
else{
this.disable = false;
}
});
},
validateFormCoupon(e) {
var _this = this;
this.$validator.validateAll().then((result) => {
if (result) {
_this.disable = true;
_this.applyCoupon(e);
}
else{
_this.disable = false;
}
});
},
// show server validation errors
serverValidate(serrors) {
this.disable = false;
this.$validator.validateAll().then((result) => {
this.$validator.errors.add(serrors);
});
},
// count total tax
countTax(price, tax, rate_type, net_price, quantity) {
price = parseFloat(price).toFixed(2);
tax = parseFloat(tax).toFixed(2);
var total_tax = parseFloat(quantity * tax).toFixed(2);
// in case of percentage
if(rate_type == 'percent')
{
if(isNaN((price * total_tax)/100))
return 0;
total_tax = (parseFloat((price*total_tax)/100)).toFixed(2);
if(net_price == 'excluding')
return total_tax+' '+this.currency+' ('+tax+'%'+' '+trans('em.exclusive')+')';
else
return total_tax+' '+this.currency+' ('+tax+'%'+' '+trans('em.inclusive')+')';
}
// for fixed tax
if(rate_type == 'fixed')
{
if(net_price == 'excluding')
return total_tax+' '+this.currency+' ('+tax+' '+this.currency+' '+trans('em.exclusive')+')';
else
return total_tax+' '+this.currency+' ('+tax+' '+this.currency+' '+trans('em.inclusive')+')';
}
return 0;
},
// count total price
totalPrice(){
if(this.quantity != null || this.quantity.length > 0)
{
let amount;
let tax;
let total_tax ;
this.quantity.forEach(function(value, key) {
total_tax = 0;
this.total_price[key] = [];
//CUSTOM
if (this.tickets[key]) {
if(this.tickets[key].is_donation <= 0){
amount = (parseFloat(value * this.tickets[key].price)).toFixed(2);
}else if( value > 0 && this.tickets[key].is_donation > 0){
amount = (parseFloat(1 * this.tickets[key].price)).toFixed(2);
}else if(value <= 0 && this.tickets[key].is_donation > 0){
this.$parent.tickets[key].price = 0;
this.is_donation[key] = 0;
amount = 0;
}
}
//CUSTOM
// amount = (parseFloat(value * this.tickets[key].price)).toFixed(2);
// when have no taxes set set total_price with actual ammount without taxes
if(Object.keys(this.total_price).length > 0)
{
this.total_price.forEach(function(v, k){
// if(Object.keys(v).length <= 0);
//CUSTOM
if(Object.keys(v).length <= 0 && !isNaN(v));
//CUSTOM
this.total_price[key] = amount;
}.bind(this))
}
if(this.tickets[key] &&
this.tickets[key].taxes &&
this.tickets[key].taxes.length > 0 &&
amount > 0) {
this.tickets[key].taxes.forEach(function(tax_v, tax_k) {
// in case of percentage
if(tax_v.rate_type == 'percent')
{
// in case of excluding
if(tax_v.net_price == 'excluding')
{
tax = isNaN((amount * tax_v.rate)/100) ? 0 : (parseFloat((amount*tax_v.rate)/100)).toFixed(2);
total_tax = parseFloat(total_tax) + parseFloat(tax);
}
}
// // in case of percentage
if(tax_v.rate_type == 'fixed')
{
tax = parseFloat(value *tax_v.rate);
// // in case of excluding
if(tax_v.net_price == 'excluding')
total_tax = parseFloat(total_tax) + parseFloat(tax);
}
}.bind(this))
}
this.total_price[key] = (parseFloat(amount) + parseFloat(total_tax)).toFixed(2);
this.total_tax[key] = total_tax;
}.bind(this));
}
},
updateItem() {
this.$emit('changeItem');
},
setDefaultQuantity() {
// only set default value once
var _this = this;
var promise = new Promise(function(resolve, reject) {
// only set default value once
if(_this.quantity.length == 1) {
_this.tickets.forEach(function(value, key) {
if(key == 0)
_this.quantity[key] = 0;
else
_this.quantity[key] = 0;
}.bind());
}
resolve(true);
});
promise.then(function(successMessage) {
_this.totalPrice();
_this.orderTotal();
/* CUSTOM start*/
_this.resetPromocode();
/* CUSTOM end*/
}, function(errorMessage) {
});
},
// count prise all booked tickets
orderTotal() {
this.total = 0
if(Object.keys(this.total_price).length > 0)
{
this.total_price.forEach(function(value, key){
//CUSTOM
if(isNaN(value))
value = 0;
//CUSTOM
this.total = (parseFloat(this.total) + parseFloat(value)).toFixed(2);
}.bind(this))
return this.total;
}
return 0;
},
totalExcludeTax() {
let total = 0
if(this.quantity != null && this.quantity.length > 0)
{
this.quantity.forEach(function(value, key){
total = parseInt(total) + parseInt(value) * parseInt(this.tickets[key].price);
}.bind(this))
return total;
}
return 0;
},
updateShowNextButton() {
const total = this.totalExcludeTax();
this.showNextButton = total > 0;
},
// total booked tickets
bookedTicketsTotal() {
let total = 0
if(this.quantity != null && this.quantity.length > 0)
{
this.quantity.forEach(function(value, key){
total = parseInt(total) + parseInt(value);
}.bind(this))
return total;
}
return 0;
},
defaultPaymentMethod() {
// if not admin
// total > 0
// if(this.is_admin <= 0 && this.bookedTicketsTotal() > 0)
// this.payment_method = 1;
//CUSTOM
// if premium order & not-admin
if(this.is_admin <= 0 && this.orderTotal() > 0 && (parseFloat(this.total) - parseFloat(this.promocode_reward)).toFixed(2) > 0)
this.payment_method = default_payment_method;
// if premium order & admin
else if(this.is_admin >= 1 && this.orderTotal() > 0 && (parseFloat(this.total) - parseFloat(this.promocode_reward)).toFixed(2) > 0)
this.payment_method = 'offline';
else
this.payment_method = default_payment_method;
if(this.is_bulk > 0)
{
this.payment_method = 'offline';
}
// for free
if((parseFloat(this.total) - parseFloat(this.promocode_reward)).toFixed(2) <= 0)
this.payment_method = 'free';
//CUSTOM
},
loginFirst() {
window.location.href = route('eventmie.login_first');
},
signupFirst() {
window.location.href = route('eventmie.signup_first');
},
// get customers
getCustomers(loading, search = null){
var postUrl = route('eventmie.get_customers');
var _this = this;
axios.post(postUrl,{
'search' :search,
}).then(res => {
var promise = new Promise(function(resolve, reject) {
_this.options = res.data.customers;
resolve(true);
})
promise
.then(function(successMessage) {
loading(false);
}, function(errorMessage) {
//error handler function is invoked
console.log(errorMessage);
})
})
.catch(error => {
let serrors = Vue.helpers.axiosErrors(error);
if (serrors.length) {
this.serverValidate(serrors);
}
});
},
// v-select methods
onSearch(search, loading) {
loading(true);
this.search(loading, search, this);
},
// v-select methods
search: _.debounce((loading, search, vm) => {
if(vm.validateEmail(search))
vm.getCustomers(loading, search);
else
loading(false);
}, 350),
validateEmail(email) {
const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
},
//CUSTOM
// stipe open modal
stripePayment(bookings_data = null) {
this.bookings_data = bookings_data;
this.$refs.stripe.stripeCheckout();
},
//apply promocode
applyPromocode(ticket_id = null, index = null){
if(this.register_user_id == null){
this.showNotification('error', trans('em.please_login'));
return true;
}
if((this.is_admin > 0 || this.is_organiser > 0) && this.customer == null){
this.showNotification('error', trans('em.select_customer'));
return true;
}
if(ticket_id != null && this.promocode[index] != null && this.promocode[index] != '' && this.promocode[index] != 'undefined'){
axios.post(route('apply_promocodes'),{
'ticket_id' : ticket_id,
'promocode' : this.promocode[index],
'customer_id' : (this.is_customer > 0) ? this.register_user_id : this.customer_id,
})
.then(res => {
if(res.data.status > 0) {
console.log('success');
var _this = this;
var promise = new Promise(function(resolve, reject) {
_this.ticket_promocodes[index] = res.data.promocode;
resolve(true);
});
promise
.then(function(successMessage) {
_this.promocodeReward();
}, function(errorMessage) {
console.log(errorMessage);
});
// success
this.pc_readonly[index] = 1;
// promocode apply button text change
document.getElementById('pcb_'+index).innerHTML = trans('em.applied');
// error field set null
document.getElementById('pc_error_'+index).innerHTML = '';
// show promocode's reward
document.getElementById('pc_success_'+index).innerHTML = res.data.promocode.reward+
(res.data.promocode.p_type == 'fixed' ? this.currency : '%')+' OFF!';
// promocode input field readonly
document.getElementById('pc_'+index).readOnly = true;
// promocode apply button disable
document.getElementById('pcb_'+index).disabled = true;
} else {
console.log('error');
// error
this.pc_readonly[index] = 0;
// promocode input field readonly
document.getElementById('pc_'+index).readOnly = false;
// error field set
document.getElementById('pc_error_'+index).innerHTML = res.data.message;
//success message set null
document.getElementById('pc_success_'+index).innerHTML = '';
// promocode input field clear
document.getElementById('pc_'+index).value = '';
// promocode v-model value set null
this.promocode[index] = '';
}
})
.catch(error => {
Vue.helpers.axiosErrors(error);
});
}
},
// promocode' reward
promocodeReward(){
this.promocode_reward = 0;
if(Object.keys(this.ticket_promocodes).length > 0){
this.ticket_promocodes.forEach(function(value, key){
if(value != 'undefined' && value != '' && value != null) {
if(value.p_type == 'fixed'){
this.promocode_reward = isNaN(parseFloat(this.promocode_reward) + parseFloat(value.reward)) ? this.promocode_reward :
(parseFloat(this.promocode_reward) + parseFloat(value.reward));
}
else {
if(this.total_price[key] > 0) {
this.promocode_reward = this.promocode_reward + (isNaN((this.total_price[key]*value.reward)/100) ? this.promocode_reward : parseFloat((this.total_price[key]*value.reward)/100));
}
}
}
}.bind(this))
}
this.defaultPaymentMethod();
return this.promocode_reward.toFixed(2);
},
// reset promocode fields
resetPromocode(){
this.quantity.forEach(function(value, key){
if(Number(value) <= 0 || value == '' || value == 'undefined' || value == null ) {
// promocode apply button disable
if (document.getElementById('pcb_'+key)) {
document.getElementById('pcb_'+key).disabled = false;
// promocode apply button text change
document.getElementById('pcb_'+key).innerHTML = trans('em.apply');
// promocode apply button disable
document.getElementById('pcb_'+key).disabled = true;
}
// promocode input field readonly
if (document.getElementById('pc_'+key)) {
document.getElementById('pc_'+key).readOnly = false;
document.getElementById('pc_'+key).value = '';
// promocode input field readonly
document.getElementById('pc_'+key).readOnly = true;
}
// success
this.pc_readonly[key] = 1;
//clear field
this.promocode[key] = '';
// error field set null
document.getElementById('pc_error_'+key) ? document.getElementById('pc_error_'+key).innerHTML = '' : '';
// show promocode's reward
document.getElementById('pc_success_'+key) ? document.getElementById('pc_success_'+key).innerHTML = '' : '';
this.ticket_promocodes[key] = '';
}
else{
if(this.promocode[key] == 'undefined' || this.promocode[key] == '') {
// promocode apply button disable
document.getElementById('pcb_'+key).disabled = false;
// promocode input field readonly
document.getElementById('pc_'+key).readOnly = false;
this.pc_readonly[key] = 0;
document.getElementById('pc_'+key).value = '';
// promocode apply button text change
document.getElementById('pcb_'+key).innerHTML = trans('em.apply');
// error field set null
document.getElementById('pc_error_'+key).innerHTML = '';
// show promocode's reward
document.getElementById('pc_success_'+key).innerHTML = '';
}
}
}.bind(this))
},
timerOnSale(sale_start_date = null, sale_end_date = null){
if(sale_start_date == null || sale_end_date == null)
return true;
var local_tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
var a = this.userTimezone(sale_end_date, 'YYYY-MM-DD HH:mm:ss').format('DD/MM/YYYY HH:mm:ss');
var b = moment().tz(local_tz).format('DD/MM/YYYY HH:mm:ss');
var ms = 0; // milliseconds
if(moment(a,"DD/MM/YYYY HH:mm:ss") > moment(b,"DD/MM/YYYY HH:mm:ss")){
ms = moment(a,"DD/MM/YYYY HH:mm:ss").tz(local_tz).diff(moment(b,"DD/MM/YYYY HH:mm:ss").tz(local_tz)); //milliseconds
}
return ms;
},
// create attenddes fields
createFields(){
this.tickets.forEach(function(v, k){
this.name[k] = [];
this.phone[k] = [];
this.address[k] = [];
}.bind(this))
},
// for input box
isDonation(){
if(this.tickets.length > 0)
{
this.tickets.forEach(function(value, key){
if(value.is_donation > 0 ){
if(this.is_donation[key] == undefined || this.is_donation[key] == ''){
this.is_donation[key] = parseFloat(0);
this.total_price[key] = parseFloat(0);
}
this.$parent.tickets[key].price = parseFloat(this.is_donation[key]).toFixed(2);
this.is_donation[key] = this.is_donation[key];
}
}.bind(this))
}
},
// for group button
setDonationValue(index = null, price = 0){
if(index == null)
return true;
if(this.tickets[index].is_donation > 0){
var id = 'donation_'+index;
document.getElementById(id).value = parseFloat(price);
this.is_donation[index] = parseFloat(price);
this.tickets[index].price = parseFloat(price);
this.quantity[index] = this.quantity[index];
this.isDonation();
this.totalPrice();
this.orderTotal();
this.$forceUpdate();
}
},
// accept only numeric value
NumbersOnly(evt) {
var evt = (evt) ? evt : window.event;
var charCode = (evt.which) ? evt.which : evt.keyCode;
if ((charCode > 31 && (charCode < 48 || charCode > 57)) && charCode !== 46) {
evt.preventDefault();;
} else {
return true;
}
},
//paystack payment
PayStack(booking_data){
this.$refs.pay_stack.PayStack(booking_data)
}
//CUSTOM
},
watch: {
quantity: function () {
//CUSTOM
this.isDonation();
//CUSTOM
this.totalPrice();
this.orderTotal();
this.defaultPaymentMethod();
this.updateShowNextButton();
/* CUSTOM */
this.resetPromocode();
this.promocodeReward();
/* CUSTOM */
},
tickets: function() {
//CUSTOM
this.isDonation();
//CUSTOM
this.updateShowNextButton();
this.totalPrice();
this.orderTotal();
},
// active when customer search
customer: function () {
this.customer_id = this.customer != null ? this.customer.id : null;
},
// CUSTOM
is_donation: function() {
this.isDonation();
this.totalPrice();
this.orderTotal();
},
// CUSTOM
},
mounted() {
this.openModal = true;
if (this.register_user_id) {
console.log('register_user_id', this.register_user_id);
if (this.is_virtual_event) {
this.checkout();
} else {
if (this.tickets.length > 0 && (this.tickets[0].t_type == 2 || this.tickets[0].t_type == 3)) {
this.selecting_seat = false;
this.t_type = 2;
} else {
this.t_type = 1;
this.getLinkSeatChartThenOpen();
}
}
}
this.setDefaultQuantity();
this.defaultPaymentMethod();
// CUSTOM
this.createFields();
// CUSTOM
},
updated() {
window.reload_currency();
}
}
</script>