FileMaster
Search
Toggle Dark Mode
Home
/
.
/
wp-content
/
plugins
/
ameliabooking
/
assets
/
views
/
frontend
/
booking
Edit File: Booking.vue
<template> <div id="amelia-booking-wrap" class="am-wrap"> <!-- Spinner --> <div class="am-spinner am-section" v-show="!empty && (!fetched || loadingCacheBookingData)"> <img class="svg-booking am-spin" :src="$root.getUrl + 'public/img/oval-spinner.svg'"> <img class="svg-booking am-hourglass" :src="$root.getUrl + 'public/img/hourglass.svg'"> </div> <div v-if="empty" class="am-no-services"> <img :src="$root.getUrl+'public/img/am-empty-booking.svg'" style="margin-top: 10px;"> <h1>{{$root.labels.oops}}</h1> <h3 v-if="$root.shortcodeData.booking.show !== 'packages'">{{$root.labels.no_services_employees}}</h3> <p v-if="$root.shortcodeData.booking.show !== 'packages'">{{$root.labels.add_services_employees}}</p> <p v-if="$root.shortcodeData.booking.show === 'packages'">{{$root.labels.no_package_services}}</p> <a href="https://wpamelia.com/services-and-categories/" rel="nofollow"> {{$root.labels.add_services_url}} </a> <span v-if="$root.shortcodeData.booking.show !== 'packages'" style="font-size:14px">{{$root.labels.and}}</span> <a v-if="$root.shortcodeData.booking.show !== 'packages'" href="https://wpamelia.com/employees/" rel="nofollow"> {{$root.labels.add_employees_url}} </a> </div> <div :id="id" class="am-step-booking-catalog" :class="$root.settings.customization.forms ? `am-form-${formType}` : ''" v-show="!empty && fetched"> <!-- Select Service Form --> <select-service-form v-if="!bookingCompleted && !activePackage && !passedPackage && !showPackagesOnly && !packageCalendarActive" :show-services="showServices" :show-locations="showLocations" :show-employees="showEmployees" :passed-service="passedService" :appointment="appointment" :group="group" :selected-extras="selectedExtras" :options="options" :fetched="fetched" :extras-error="extrasError" :form-type="formType" :forms-data="forms[formType]" :loading-time-slots="loadingTimeSlots" @change="changeFormItem" @getSlots="getTimeSlots" @enableGrouping="enableGrouping" ></select-service-form> <!-- /Select Service Form --> <!-- Recurring Setup Form --> <recurring-setup v-if="activeRecurringSetup && !bookingCompleted" :containerId="id" :initialRecurringData="initialRecurringData" :recurringData="recurringData" :disabledWeekdays="disabledWeekdays" :availableDates="availableDates" :calendarTimeSlots="calendarTimeSlots" :occupiedTimeSlots="occupiedTimeSlots" :service="getServiceById(appointment.serviceId)" :isFrontend="true" :form-type="formType" :forms-data="forms[formType]" @cancelRecurringSetup="cancelRecurringSetup" @confirmRecurringSetup="confirmRecurringSetup" > </recurring-setup> <!-- /Recurring Setup Form --> <!-- Recurring Dates Form --> <recurring-dates v-if="activeRecurringDates && !bookingCompleted" dialogClass="am-recurring-dates" :recurringData="recurringData" :availableDates="availableDates" :calendarTimeSlots="calendarTimeSlots" :isFrontend="true" :service="getServiceById(appointment.serviceId)" :selectedExtras="selectedExtras" :form-type="formType" :forms-data="forms[formType]" @confirmRecurringDates="confirmRecurringDates" @cancelRecurringDates="cancelRecurringDates" > </recurring-dates> <!-- /Recurring Dates Form --> <!-- Calendar Date Time Form --> <calendar-date-time-form v-if="!bookingCompleted && !activeRecurringSetup && !activePackage && !passedPackage && !showPackagesOnly && !packageCalendarActive" :id="id" :selected-date="selectedDate" :available-dates="availableDates" :disabled-weekdays="disabledWeekdays" :disabled-attribute="disabledAttribute" :calendar-id="calendarId" :show-times="showTimes" :appointment="appointment" :available-time-slots="availableTimeSlots" :is-recurring-available="isRecurringAvailable" :active-recurring="activeRecurring" :show-calendar-back-button="showCalendarBackButton" :show-calendar-continue-button="showCalendarContinueButton" :loading="loading" :loading-time-slots="loadingTimeSlots" :durations="getDurations()" :form-type="formType" :forms-data="forms[formType]" @selectDuration="getTimeSlots" @selectDate="selectDate" @setTimeSlots="setTimeSlots" @selectTime="selectTime" @changeMonth="changeMonth" @togglePicker="togglePicker" @showNextScreen="showNextScreen" @changeRecurring="changeActiveRecurring" ></calendar-date-time-form> <!-- /Calendar Date Time Form --> <!-- Select Package Form --> <select-package-form v-if="!bookingCompleted && !activePackage && !passedPackage && !packageListShown && !activeConfirm && showPackagesOnly" :selected-package-id="selectedPackageId" :fetched="fetched" :options="options" :form-type="formType" :forms-data="forms[formType]" @continuePackage="continuePackage" ></select-package-form> <!-- /Select Package Form --> <!-- Package Info Form --> <package-info v-if="!bookingCompleted && activePackage && !passedPackage" class="am-package-selected" :id="id" :fetched-slots="fetchedSlots" :selected-package="selectedPackage" :package-slots-fetched="packageSlotsFetched" :has-back="packagesHaveBack" :has-header="true" :form-type="formType" :forms-data="forms[formType]" @showPackageCalendar="packageServiceSelected++" @closePackage="closePackage" @packageSlotsSelectedCallback="packageSlotsSelectedCallback" > </package-info> <!-- /Package Info Form --> <!-- Package Setup Form --> <package-setup v-if="!bookingCompleted && (selectedPackage ? selectedPackage.hasSlots : true) && packageCalendarActive" class="am-select-date am-select-service-date-transition am-package-setup" :id="id" :options="options" :selectedPackage="selectedPackage" :packageServiceSelected="packageServiceSelected" :packageCreated="packageCreated" :isPassedPackage="!!passedPackage" :disableFetchSlots="disableFetchPackageSlots" :form-type="formType" :forms-data="forms[formType]" @packageSlotsFetchedCallback="packageSlotsFetchedCallback" @packageSlotsSelectedCallback="packageSlotsSelectedCallback" @packageListShow="packageListShow" > </package-setup> <!-- /Package Setup Form --> <!-- Package List Form --> <package-list v-if="!bookingCompleted && packageListShown" :container-id="'amelia-app-booking' + $root.shortcodeData.counter" :bookable="getBookablePackageData()" :has-header="!passedPackage" :quantity="selectedPackage.sharedCapacity ? selectedPackage.quantity : 0" :form-type="formType" :forms-data="forms[formType]" @cancelBooking="cancelPackageList" @packageSlotsSelectedCallback="packageSlotsSelectedCallback" > </package-list> <!-- /Package List Form --> <!-- Confirm Booking --> <confirm-booking v-if="activeConfirm && !bookingCompleted" dialogClass="am-confirm-booking am-scroll" v-bind="cacheData && (cacheData.status === 'canceled' || cacheData.status === 'failed') ? getCacheDataRequestProps() : { bookableType: selectedPackage === null ? 'appointment' : 'package', containerId: getContainerId(), taxes: options.entities.taxes, bookable: getBookableData(), appointment: appointment, marketing: marketing, provider: selectedProvider, location: selectedLocation, service: selectedService, customFields: options.entities.customFields, recurringData: getRecurringAppointmentsData(), packageData: selectedPackage === null ? null : getPackageAppointmentsData(), recurringString: recurringData.recurringString + ' ' + recurringData.untilString, hasCancel: !passedPackage || passedPackage.hasSlots, hasHeader: !passedPackage, phonePopulated: phonePopulated, passedCategoryId: passedCategory ? passedCategory.id : null, queryParams: [] }" :form-type="formType" :forms-data="forms[formType]" @confirmedBooking="confirmedBooking" @cancelBooking="cancelBooking" > </confirm-booking> <!-- /Confirm Booking --> <!-- Add To Calendar --> <transition name="fade"> <add-to-calendar v-if="showAddToCalendar" ref="congratulations" :addToCalendarData="addToCalendarData" :form-type="formType" :forms-data="forms[formType]" @closeDialogAddToCalendar="closeDialogAddToCalendar" ></add-to-calendar> </transition> <!-- /Add To Calendar --> </div> <div v-if="$root.licence.isLite && $root.settings.general.backLink.enabled" class="am-lite-footer"> <a rel="nofollow" class="am-lite-footer-link" :href="$root.settings.general.backLink.url" target="_blank" > {{ $root.settings.general.backLink.label }} </a> </div> </div> </template> <script> import moment from 'moment' import marketingMixin from '../../../js/frontend/mixins/marketingMixin' import cacheMixin from '../../../js/frontend/mixins/cacheMixin' import formsCustomizationMixin from '../../../js/common/mixins/formsCustomizationMixin' import imageMixin from '../../../js/common/mixins/imageMixin' import dateMixin from '../../../js/common/mixins/dateMixin' import priceMixin from '../../../js/common/mixins/priceMixin' import servicePriceMixin from '../../../js/common/mixins/servicePriceMixin' import helperMixin from '../../../js/backend/mixins/helperMixin' import settingsMixin from '../../../js/common/mixins/settingsMixin' import entitiesMixin from '../../../js/common/mixins/entitiesMixin' import recurringMixin from '../../../js/common/mixins/recurringMixin' import packageMixin from '../../../js/frontend/mixins/packageMixin' import durationMixin from '../../../js/common/mixins/durationMixin' import customFieldMixin from '../../../js/common/mixins/customFieldMixin' import bookingMixin from '../../../js/frontend/mixins/bookingMixin' import slotsMixin from '../../../js/common/mixins/slotsMixin' import selectServiceForm from './components/formSteps/SelectServiceForm' import calendarDateTimeForm from './components/formSteps/CalendarDateTimeForm' import recurringSetup from '../../parts/RecurringSetup.vue' import recurringDates from '../../parts/RecurringDates.vue' import selectPackageForm from './components/formSteps/SelectPackageForm' import packageInfo from '../package/Package.vue' import packageSetup from '../package/PackageSetup.vue' import packageList from '../package/PackageList.vue' import confirmBooking from '../parts/ConfirmBooking.vue' import addToCalendar from '../parts/AddToCalendar.vue' export default { mixins: [ slotsMixin, cacheMixin, formsCustomizationMixin, packageMixin, recurringMixin, imageMixin, dateMixin, entitiesMixin, bookingMixin, helperMixin, durationMixin, priceMixin, servicePriceMixin, customFieldMixin, settingsMixin ], props: { id: { default: 'am-step-booking' }, showService: { type: Boolean, default: true }, addToCalendarProperty: { type: Object, default: () => { return { visible: true } } }, passedService: { default: () => {}, type: Object }, passedPackage: { default: () => {}, type: Object }, passedCategory: { default: () => {}, type: Object }, passedEntities: { default: () => {}, type: Object }, passedEntitiesRelations: { default: () => {}, type: Object }, formType: { type: String, default: 'stepByStepForm' } }, data () { return { empty: false, packagesHaveBack: true, showPackagesOnly: false, selectedWeekIndex: 0, selectedProvider: null, selectedLocation: null, selectedService: null, loading: false, isRecurringAvailable: false, initialRecurringData: null, recurringData: { dates: [], startAppointment: null, startDate: null, startTime: null, pageRecurringDates: [], pagination: { show: this.$root.settings.general.itemsPerPage, page: 1, count: 0 }, recurringString: '', untilString: '', datesCallback: null, setupCallback: null }, activeRecurring: false, activeRecurringSetup: false, activeRecurringDates: false, selectedMonth: moment().format('YYYY-MM'), isServiceChanged: true, calendarId: '', activeConfirm: false, bookingCompleted: false, activePicker: false, packageCalendarActive: false, addToCalendarData: null, appointment: { bookingStart: '', bookingStartTime: '', bookings: [{ customer: { email: '', externalId: null, firstName: '', id: null, lastName: '', phone: '' }, customFields: {}, customerId: 0, extras: [], persons: 1, haveMandatoryExtras: false, minSelectedExtras: 0 }], duration: 0, group: false, notifyParticipants: this.$root.settings.notifications.notifyCustomers, payment: { amount: 0, gateway: '', data: {} }, categoryId: null, providerId: 0, serviceId: null, locationId: null }, availableDates: [], availableTimeSlots: [], calendar: '', calendarTimeSlots: {}, occupiedTimeSlots: {}, pricedCalendarTimeSlots: {}, pricedOccupiedTimeSlots: {}, bookedTimeSlots: {}, calendarVisible: false, customer: { name: '', email: '', phone: '', paymentMethod: '' }, customerRules: { name: [ {required: true, message: 'Please input name', trigger: 'submit'}, {min: 3, max: 50, message: 'Length should be 3 to 50', trigger: 'submit'}], email: [ {required: true, message: 'Please input name', trigger: 'submit'}, {min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'submit'}], phone: '', paymentMethod: '' }, disabledAttribute: { contentStyle: { color: '#ccc', opacity: 0.4, textDecoration: 'line-through' } }, disabledWeekdays: null, fetched: false, fetchedSlots: false, group: { allowed: false, enabled: false, count: 1, options: [] }, loadingTimeSlots: false, slotsIndexStarted: 0, responseEntities: { taxes: [], categories: [], employees: [], locations: [], services: [] }, options: { availableEntitiesIds: { categories: [], employees: [], locations: [], services: [] }, entitiesRelations: {}, entities: { taxes: [], packages: [], services: [], employees: [], locations: [], customFields: [] } }, marketing: { service: null, employee: null, location: null, category: null, package: null, payment: null }, selectedExtras: [], previouslySelectedExtras: [], selectedDate: null, showAddToCalendar: false, showExtras: false, showFilters: false, showTimes: false, showServices: false, showEmployees: false, showLocations: false, extrasMandatory: false, showCalendarBackButton: false, showCalendarContinueButton: false, times: '', extrasError: [], forms: {} } }, created () { this.forms = this.getTranslatedForms('stepByStepForm') this.calendarId = 'am-appointment-times' + this.$root.shortcodeData.counter window.addEventListener('resize', this.handleResize) }, mounted () { if (this.addToCalendarProperty.visible) { this.setCacheData(this.getContainerId(), true) } else { this.showAddToCalendar = false } if (!this.$root.shortcodeData.hasBookingShortcode || !this.$root.shortcodeData.hasCategoryShortcode) { this.inlineBookingSVG() } if (this.passedService) { this.checkMandatoryExtras(this.passedService) } // Customization hook if ('beforeBookingLoaded' in window) { window.beforeBookingLoaded(this) } if (this.passedEntities && !this.passedPackage) { this.options.isFrontEnd = true this.options.entitiesRelations = Object.assign({}, this.passedEntitiesRelations) let shortCodeEntitiesIds = this.getShortCodeEntityIds() this.filterEntities(this.passedEntities, { categoryId: this.passedService.categoryId, serviceId: this.passedService.id, employeeId: shortCodeEntitiesIds.employeeId, locationId: shortCodeEntitiesIds.locationId }) this.fetchedEntities() this.times = document.getElementById(this.calendarId) } else if (!this.passedPackage) { let shortCodeEntitiesIds = this.getShortCodeEntityIds() if (shortCodeEntitiesIds.show === 'packages') { this.showPackagesOnly = true this.packageCalendarActive = true } else if (shortCodeEntitiesIds.show === 'services') { this.showPackagesOnly = false } let $this = this this.fetchEntities(function (success) { if (success) { $this.fetchedEntities() } }, { types: ['locations', 'employees', 'categories', 'custom_fields', 'packages', 'taxes'], isFrontEnd: true, isPanel: false }) this.times = document.getElementById(this.calendarId) } else if (this.passedPackage) { this.options.isFrontEnd = true this.options.entitiesRelations = Object.assign({}, this.passedEntitiesRelations) this.options.entities = this.passedEntities this.setBookingCustomFields() this.selectPackage(this.passedPackage) if (!this.passedPackage.hasSlots || this.loadingCacheBookingData) { this.fetched = true this.packageSlotsSelectedCallback() this.runCacheAction() } if (this.options.entities.services.length === 0 || this.options.entities.employees.length === 0) this.empty = true } }, updated () { this.handleResize() }, methods: { changeFormItem (fieldObj) { if (fieldObj.identifier === 'changeService') { this.changeService() if (marketingMixin.hasAmeliaTracking(this.$root.marketing, this.appointment.serviceId)) { this.marketing.service = this.getServiceById(this.appointment.serviceId) this.marketing.category = this.marketing.service ? this.getCategoryById(this.marketing.service.categoryId) : null marketingMixin.trackAmeliaData(this, this.$root.marketing, 'appointment', 'SelectService') } } if (fieldObj.identifier === 'selectPackage') { this.selectPackage(fieldObj.value) if (marketingMixin.hasAmeliaTracking(this.$root.marketing, fieldObj.value.id)) { this.marketing.package = this.getPackageById(fieldObj.value.id) marketingMixin.trackAmeliaData(this, this.$root.marketing, 'package', 'SelectPackage') } } if (fieldObj.identifier === 'changeLocation') { this.changeLocation(fieldObj.required) if (marketingMixin.hasAmeliaTracking(this.$root.marketing, this.appointment.locationId)) { this.marketing.location = this.getLocationById(this.appointment.locationId) marketingMixin.trackAmeliaData(this, this.$root.marketing, 'appointment', 'SelectLocation') } } if (fieldObj.identifier === 'changeEmployee') { this.changeEmployee(fieldObj.required) if (marketingMixin.hasAmeliaTracking(this.$root.marketing, this.appointment.providerId)) { this.marketing.employee = this.getProviderById(this.appointment.providerId) marketingMixin.trackAmeliaData(this, this.$root.marketing, 'appointment', 'SelectEmployee') } } if (fieldObj.identifier === 'enableGrouping') { this.enableGrouping() } if (fieldObj.identifier === 'changeNumberOfPersons') { this.changeNumberOfPersons() } if (fieldObj.identifier === 'addExtra') { this.addExtra() } if (fieldObj.identifier === 'changeSelectedExtra') { this.changeSelectedExtra(fieldObj.value, fieldObj.key) } if (fieldObj.identifier === 'deleteExtra') { this.deleteExtra(fieldObj.value) } }, changeActiveRecurring (recurring) { this.activeRecurring = recurring }, runCacheAction () { if (this.loadingCacheBookingData) { if (this.cacheData.status === 'canceled' || this.cacheData.status === 'failed') { this.showConfirmBooking() } else if (this.cacheData.status === 'paid' || this.cacheData.status === null) { this.confirmedBooking(this.cacheData.response, true, this.cacheData.request) } this.loadingCacheBookingData = false } }, getContainerId () { return 'amelia-app-booking' + this.$root.shortcodeData.counter }, showConfirmBooking () { this.activeConfirm = true this.loading = true let amContainer = document.getElementById(this.id) setTimeout(() => { this.loading = false this.loadingCacheBookingData = false amContainer.classList.toggle('am-active-picker', false) amContainer.classList.toggle('am-active-confirm', this.activeConfirm) }, 500) }, checkMandatoryExtras (service) { this.appointment.bookings[0].haveMandatoryExtras = service.mandatoryExtra this.appointment.bookings[0].minSelectedExtras = service.minSelectedExtras for (let i = 0; i < service.minSelectedExtras; i++) { if (service.mandatoryExtra) { this.extrasMandatory = true this.addExtra() } } }, getBookableData () { if (this.selectedPackage === null) { this.selectedService = this.getProviderById(this.selectedProvider.id).serviceList.find(service => service.id === this.appointment.serviceId) if (marketingMixin.hasAmeliaTracking(this)) { this.marketing.service = this.selectedService this.marketing.employee = this.selectedProvider this.marketing.location = this.selectedLocation this.marketing.category = this.getCategoryById(this.selectedService.categoryId) } return { id: this.selectedService.id, name: this.selectedService.name, price: this.getBookingServicePrice( this.selectedService, this.appointment.serviceDuration, this.appointment.bookings[0].persons, this.appointment.providerId, this.appointment.bookingStart ), depositData: this.selectedService.depositPayment !== 'disabled' ? { deposit: this.selectedService.deposit, depositPayment: this.selectedService.depositPayment, depositPerPerson: this.selectedService.depositPerPerson, depositFullPayment: this.selectedService.fullPayment } : null, maxCapacity: this.selectedService.maxCapacity, pictureThumbPath: this.selectedService.pictureThumbPath, aggregatedPrice: this.selectedService.aggregatedPrice, bookingStart: this.appointment.bookingStart } } else { return { id: this.selectedPackage.id, name: this.selectedPackage.name, price: this.getPackagePrice(this.selectedPackage), depositData: this.selectedPackage.depositPayment !== 'disabled' ? { deposit: this.selectedPackage.deposit, depositPayment: this.selectedPackage.depositPayment, depositPerPerson: this.selectedPackage.depositPerPerson, depositFullPayment: this.selectedPackage.fullPayment } : null, calculatedPrice: this.selectedPackage.calculatedPrice, discount: this.selectedPackage.discount, maxCapacity: 1, pictureThumbPath: this.selectedPackage.pictureThumbPath, aggregatedPrice: this.selectedPackage.aggregatedPrice } } }, changeMonth (page) { this.selectedMonth = page ? moment().year(page.year).month(page.month - 1).date(1).format('YYYY-MM') : null }, showCalendarOnly (initCall) { let providerService = null if (this.appointment.serviceId && this.appointment.providerId) { providerService = this.getProviderService(this.appointment.providerId, this.appointment.serviceId) } let service = null if (this.appointment.serviceId) { service = this.getServiceById(this.appointment.serviceId) } let serviceProviderVisibility = true let servicePackageVisibility = true let serviceLocationVisibility = true let addExtraVisibility = true for (const key in this.forms[this.formType].selectServiceForm.itemsDraggable) { if (this.forms[this.formType].selectServiceForm.itemsDraggable[key].hasOwnProperty('visibility') && !this.forms[this.formType].selectServiceForm.itemsDraggable[key].visibility) { if (key === 'employeeFormField') { serviceProviderVisibility = false } if (key === 'servicePackageFormField') { servicePackageVisibility = false } if (key === 'locationFormField') { serviceLocationVisibility = false } if (key === 'addExtraFormField') { addExtraVisibility = false } } } let anyEmployeeHasBringingAnyone = false if (providerService === null) { this.employeesFiltered.forEach((employeeItem) => { employeeItem.serviceList.forEach((serviceItem) => { if (service && serviceItem.id === service.id && serviceItem.maxCapacity > 1 && serviceItem.bringingAnyone) { anyEmployeeHasBringingAnyone = true } }) }) } return initCall && !this.showServices && (!serviceProviderVisibility || !this.showEmployees) && (!serviceLocationVisibility || !this.showLocations) && (service && service.extras.length ? !this.extrasMandatory : true) && (service && service.extras.length ? !addExtraVisibility : true) && (!serviceProviderVisibility || this.employeesFiltered.length === 1) && ( (providerService !== null && (providerService.maxCapacity === 1 || providerService.bringingAnyone === false)) || (providerService === null && !anyEmployeeHasBringingAnyone) ) && (!servicePackageVisibility || (typeof this.passedService === 'undefined' ? this.options.entities.packages.length === 0 : true)) }, changeService () { if ('ameliaBooking' in window && 'changedEntity' in window.ameliaBooking) { window.ameliaBooking.changedEntity('service', this.appointment) } if (this.appointment.serviceId) { let selectedService = this.getServiceById(this.appointment.serviceId) this.appointment.serviceDuration = selectedService.duration if (selectedService.mandatoryExtra) { this.closePicker() } this.updateSettings(selectedService.settings) this.isServiceChanged = true // this.clearValidation() this.extrasError = [] this.appointment.bookings[0].extras = [] this.selectedExtras = [] this.checkMandatoryExtras(selectedService) this.handleCapacity(true, false, selectedService.maxExtraPeople) this.toggleRecurringActive() if (this.calendarVisible) { this.getTimeSlots() } } else { this.cancelRecurringSetup() setTimeout(() => { this.selectedDate = null this.closePicker() this.resetAppointment() this.unSelectTime() this.activeRecurringSetup = false this.showTimes = false }, 200) } }, changeEmployee (required = false) { let selectedService = null if (this.appointment.serviceId) { selectedService = this.getServiceById(this.appointment.serviceId) } this.handleCapacity(true, false, selectedService ? selectedService.maxExtraPeople : null) if (this.calendarVisible && this.appointment.providerId) { this.getTimeSlots() } if (required && !this.appointment.providerId) { this.cancelRecurringSetup() setTimeout(() => { this.selectedDate = null this.closePicker() this.resetAppointment() this.unSelectTime() this.activeRecurringSetup = false this.showTimes = false }, 200) } }, changeLocation (required = false) { if (this.calendarVisible && this.appointment.locationId) { this.getTimeSlots() } if (!this.appointment.locationId) { this.appointment.locationId = null } if (required && !this.appointment.locationId) { this.cancelRecurringSetup() setTimeout(() => { this.selectedDate = null this.closePicker() this.resetAppointment() this.unSelectTime() this.activeRecurringSetup = false this.showTimes = false }, 200) } }, enableGrouping () { let selectedService = null if (this.appointment.serviceId) { selectedService = this.getServiceById(this.appointment.serviceId) } this.handleCapacity(true, true, selectedService ? selectedService.maxExtraPeople : null) this.group.enabled === true ? this.appointment.bookings[0].persons += 1 : this.appointment.bookings[0].persons = 1 if (this.calendarVisible) { this.getTimeSlots() } }, changeNumberOfPersons () { if (this.calendarVisible) { this.getTimeSlots() } }, getSelectedExtraMaxQuantity (selectedExtra) { let extra = this.getServiceById(this.appointment.serviceId).extras.find(extra => extra.id === selectedExtra.id) return typeof extra !== 'undefined' ? extra.maxQuantity : '' }, getAvailableExtras (selectedExtra) { let selectedExtras = [] let availableExtras = [] this.selectedExtras.forEach(function (extra) { if (extra.id) { selectedExtras.push(extra.id) } }) this.getServiceById(this.appointment.serviceId).extras.forEach(function (extra) { if (selectedExtras.indexOf(extra.id) === -1 || selectedExtra.id === extra.id) { availableExtras.push(extra) } }) return availableExtras }, addExtra () { this.selectedExtras.push({ id: null, extraId: null, quantity: '', duration: 0, name: '' }) this.previouslySelectedExtras.push({ id: null, extraId: null, quantity: '', duration: 0, name: '' }) }, deleteExtra (key) { if (this.calendarVisible && !!this.selectedExtras[key].duration) { this.selectedExtras.splice(key, 1) this.previouslySelectedExtras.splice(key, 1) this.getTimeSlots() } else { this.selectedExtras.splice(key, 1) this.previouslySelectedExtras.splice(key, 1) } }, changeSelectedExtra (selectedExtra, key) { this.extrasError = [] if (this.previouslySelectedExtras && (key in this.previouslySelectedExtras) && this.previouslySelectedExtras[key].extraId === null) { this.previouslySelectedExtras[key].extraId = selectedExtra.extraId this.previouslySelectedExtras[key].duration = selectedExtra.duration } else { this.previouslySelectedExtras[key] = {} } selectedExtra.quantity = (selectedExtra.quantity === '') ? 1 : selectedExtra.quantity let extra = this.getServiceById(this.appointment.serviceId).extras.find(extra => extra.id === selectedExtra.id) selectedExtra.extraId = extra.id selectedExtra.duration = extra.duration selectedExtra.name = extra.name selectedExtra.price = extra.price selectedExtra.selected = true selectedExtra.aggregatedPrice = extra.aggregatedPrice if (selectedExtra.quantity > extra.maxQuantity) { selectedExtra.quantity = extra.maxQuantity } if (this.calendarVisible && (!!extra.duration || (this.previouslySelectedExtras[key].duration !== null && selectedExtra.duration === null))) { this.getTimeSlots() } this.previouslySelectedExtras[key].extraId = selectedExtra.extraId this.previouslySelectedExtras[key].duration = selectedExtra.duration }, fetchedEntities () { if (this.$root.shortcodeData.booking.service && this.$root.shortcodeData.booking.service.length) { this.checkMandatoryExtras(this.options.entities.services[0]) } if (this.options.entities.services.length === 0 || this.options.entities.employees.length === 0 || (this.$root.shortcodeData.booking.show === 'packages' && this.options.entities.packages.length === 0) ) { this.empty = true } this.setBookingCustomFields() if (this.employeesFiltered.length === 1) { this.appointment.providerId = this.employeesFiltered[0].id this.$root.shortcodeData.booking.employee = this.appointment.providerId } else if (this.employeesFiltered.length > 1) { this.showEmployees = true } else { return } if (this.locationsFiltered.length === 1) { this.appointment.locationId = this.locationsFiltered[0].id this.$root.shortcodeData.booking.location = this.appointment.locationId } else if (this.locationsFiltered.length > 1) { this.showLocations = true } if (this.servicesFiltered.length === 1) { this.appointment.serviceId = this.servicesFiltered[0].id this.$root.shortcodeData.booking.service = this.appointment.serviceId } else if (this.servicesFiltered.length > 1) { this.showServices = true } else { return } this.toggleRecurringActive() let service = null if (this.appointment.serviceId) { service = this.getServiceById(this.appointment.serviceId) this.appointment.serviceDuration = service.duration this.updateSettings(service.settings) } this.handleCapacity(true, false, service ? service.maxExtraPeople : null) if (('showAmeliaCalendarOnLoad' in window && window.showAmeliaCalendarOnLoad && this.appointment.serviceId) || (this.showCalendarOnly(true) && this.$root.shortcodeData.booking.show !== 'packages') ) { document.getElementById(this.id + '-calendar').classList.remove('am-select-service-date-transition') this.getTimeSlots() } else { let shortCodeEntitiesIds = this.getShortCodeEntityIds() if (shortCodeEntitiesIds.show === 'packages') { this.options.entities.packages.sort((a, b) => a.position - b.position) if (this.options.entities.packages.length === 1) { this.selectedPackageId = this.options.entities.packages[0].id this.packagesHaveBack = false this.selectPackage(this.getPackageById(this.selectedPackageId)) } } this.fetched = true this.runCacheAction() } }, getPossibleProvidersIfNoneSelected () { let providers = [] // If Employee is not selected, select ones that can provide the service if (!this.appointment.providerId) { // If grouping is enabled check employees capacity for selected service if (this.group.enabled) { this.employeesFiltered.forEach((employee) => { if (typeof (employee.serviceList.find(service => service.id === this.appointment.serviceId && service.maxCapacity >= this.appointment.bookings[0].persons)) !== 'undefined') { providers.push(employee) } }) } else { this.employeesFiltered.forEach((employee) => { if (typeof (employee.serviceList.find(service => service.id === this.appointment.serviceId)) !== 'undefined') { providers.push(employee) } }) } } return providers }, getTimeSlots (formValidation = true) { this.getCurrentUser() let service = this.appointment.serviceId ? this.getServiceById(this.appointment.serviceId) : null this.selectedExtras.forEach((extra, index) => { if (service && service.mandatoryExtra && !extra.id && this.appointment.bookings[0].minSelectedExtras > index) { this.extrasError.push(index) } }) if (this.extrasError.length) { return false } if (this.appointment.serviceId && formValidation) { this.loadingTimeSlots = true let extras = [] this.selectedExtras.forEach(function (extra) { if (extra.id) { extras.push({ id: extra.id, quantity: extra.quantity }) } }) // Customization hook if ('afterBookingSelectService' in window) { window.afterBookingSelectService(this.appointment, this.getServiceById(this.appointment.serviceId), this.getProviderById(this.appointment.providerId), this.getLocationById(this.appointment.locationId)) } this.slotsIndexStarted++ let currentIndex = this.slotsIndexStarted this.$http.get(`${this.$root.getAjaxUrl}/slots`, { params: this.getAppropriateUrlParams({ locationId: this.appointment.locationId, serviceId: this.appointment.serviceId, serviceDuration: this.appointment.serviceDuration, providerIds: this.appointment.providerId ? [this.appointment.providerId] : this.getPossibleProvidersIfNoneSelected().map(i => i.id), extras: JSON.stringify(extras), group: 1, page: 'booking', persons: this.appointment.bookings[0].persons, structured: true }) }).then(response => { if (currentIndex < this.slotsIndexStarted) { this.fetchedSlots = true this.fetched = true this.loadingTimeSlots = false return } let dateSlots = this.$root.settings.general.showClientTimeZone ? this.getConvertedTimeSlots(response.data.data.slots) : response.data.data.slots let occupiedSlots = this.$root.settings.general.showClientTimeZone ? this.getConvertedTimeSlots(response.data.data.occupied) : response.data.data.occupied if (!this.calendarVisible) { this.activePicker = !this.activePicker document.getElementById(this.id).classList.toggle('am-active-picker', this.activePicker) } let availableDates = [] let minDate = null this.useSortedDateStrings(Object.keys(dateSlots)).forEach(function (dateString) { if (minDate === null) { minDate = dateString } availableDates.push(moment(dateString).toDate()) }) this.showFirstEventMonth(minDate) let unstructuredTimeSlots = {} Object.keys(dateSlots).forEach((date) => { unstructuredTimeSlots[date] = {} Object.keys(dateSlots[date]).forEach((time) => { unstructuredTimeSlots[date][time] = [] dateSlots[date][time].forEach((slot) => { unstructuredTimeSlots[date][time].push([slot.e, slot.l].concat('c' in slot ? [slot.c, slot.s, slot.d] : [])) }) }) }) let unstructuredOccupiedTimeSlots = {} Object.keys(occupiedSlots).forEach((date) => { unstructuredOccupiedTimeSlots[date] = {} Object.keys(occupiedSlots[date]).forEach((time) => { unstructuredOccupiedTimeSlots[date][time] = [] occupiedSlots[date][time].forEach((slot) => { unstructuredOccupiedTimeSlots[date][time].push([slot.e, slot.l].concat('c' in slot ? [slot.c, slot.s, slot.d] : [])) }) }) }) this.pricedCalendarTimeSlots = dateSlots this.pricedOccupiedTimeSlots = occupiedSlots this.calendarTimeSlots = unstructuredTimeSlots this.occupiedTimeSlots = unstructuredOccupiedTimeSlots this.disabledWeekdays = {weekdays: []} this.disabledWeekdays = (availableDates.length === 0) ? {weekdays: [1, 2, 3, 4, 5, 6, 7]} : null this.availableDates = availableDates this.calendarVisible = true if (this.availableDates.length) { this.setTimeSlots() } if (!this.availableDates.length || !this.isSelectedDateAvailable()) { this.showTimes = false let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-show-times') } let dateIsNotAvailable = !this.availableDates.length || !this.isSelectedDateAvailable() let timeIsNotAvailable = (this.appointment.bookingStartTime && this.availableTimeSlots.indexOf(this.appointment.bookingStartTime) === -1) if (dateIsNotAvailable || timeIsNotAvailable) { if (dateIsNotAvailable) { this.selectedDate = null } this.unSelectTime() } if (this.activeRecurringSetup) { let amContainer = document.getElementById(this.id) amContainer.classList.add('am-show-calendar') this.activeRecurringSetup = false if (!dateIsNotAvailable) { this.showTimeSlots() } else { this.times = document.getElementById(this.calendarId) } } this.fetchedSlots = true this.fetched = true this.loadingTimeSlots = false this.runCacheAction() }).catch(e => { console.log(e.message) this.fetchedSlots = true this.fetched = true }) } }, showFirstEventMonth (minDate) { if (this.isServiceChanged && ( (this.selectedDate === null && moment(this.selectedMonth).format('YYYY-MM') !== moment(minDate, 'YYYY-MM-DD').format('YYYY-MM')) || (this.selectedDate !== null && moment(this.selectedDate).format('YYYY-MM') !== moment(minDate, 'YYYY-MM-DD').format('YYYY-MM')) )) { this.selectedDate = moment(minDate).toDate() let $this = this setTimeout(function () { $this.selectedDate = null }, 100) } this.isServiceChanged = false }, addSlotsElementToWeekRow (weekRow) { if (!this.times) { this.times = document.getElementById(this.calendarId) } weekRow.parentNode.insertBefore(this.times, weekRow.nextSibling) this.isRecurringAvailable = this.getServiceById(this.appointment.serviceId).recurringCycle !== 'disabled' setTimeout(() => { if (this.availableTimeSlots.length && this.selectedDate) { if (moment(this.selectedDate).format('YYYY-MM-DD') === moment(this.availableDates[this.availableDates.length - 1]).format('YYYY-MM-DD')) { this.activeRecurring = false this.isRecurringAvailable = false } this.showTimes = true let amContainer = document.getElementById(this.id) amContainer.classList.add('am-show-times') this.appointment.bookingStartTime = this.availableTimeSlots[0] this.selectedWeekIndex = [...weekRow.parentNode.children].indexOf(weekRow) this.selectTime() } }, 200) }, selectDate (dayInfo, calendarDate) { this.selectedDate = calendarDate this.unSelectTime() let isDisabled = false dayInfo.attributes.forEach(function (attrItem) { if (attrItem.hasOwnProperty('key') && attrItem['key'] === 'disabled') { isDisabled = true } }) if (isDisabled) { return } let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-show-times') this.showTimes = false if (dayInfo.inMonth) { let weekRowInMonth = dayInfo.event.target.parentNode.parentNode.parentNode.parentNode.parentNode if (weekRowInMonth.classList.contains('c-day')) { weekRowInMonth = dayInfo.event.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode } if (!weekRowInMonth.classList.contains('c-week')) { weekRowInMonth = dayInfo.event.target.parentNode.parentNode.parentNode.parentNode } if (!weekRowInMonth.classList.contains('c-week')) { weekRowInMonth = dayInfo.event.target.parentNode.parentNode.parentNode } this.addSlotsElementToWeekRow(weekRowInMonth) } else { setTimeout(() => { let weekRowNotInMonth = document.getElementById(this.id + '-calendar') .getElementsByClassName('c-weeks-rows')[0].children[dayInfo.weekdayOrdinal - 1] this.addSlotsElementToWeekRow(weekRowNotInMonth) }, 1000) } }, isSelectedDateAvailable () { let momentDate = moment(this.selectedDate) return this.calendarTimeSlots.hasOwnProperty(momentDate.format('YYYY-MM-DD')) }, setTimeSlots (calendarDate) { if (typeof calendarDate !== 'undefined') { this.selectedDate = calendarDate } let momentDate = moment(this.selectedDate) let dateString = momentDate.format('YYYY-MM-DD') if (this.isSelectedDateAvailable()) { this.availableTimeSlots = Object.keys(this.calendarTimeSlots[dateString]) this.appointment.duration = this.getAppointmentDuration( this.appointment.serviceDuration ? parseInt(this.appointment.serviceDuration) : this.getServiceById(this.appointment.serviceId).duration, this.selectedExtras ) } }, togglePicker () { this.calendarVisible = false this.activePicker = !this.activePicker let amContainer = document.getElementById(this.id) amContainer.classList.toggle('am-active-picker', this.activePicker) }, closePicker () { this.calendarVisible = false this.activePicker = false let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-active-picker') this.isRecurringAvailable = false this.activeRecurring = false }, selectTime () { this.appointment.bookingStart = moment(this.selectedDate).format('YYYY-MM-DD') + ' ' + this.appointment.bookingStartTime this.showCalendarContinueButton = true if ('afterBookingTimeSelected' in window) { window.afterBookingTimeSelected(this.appointment) } if ('ameliaBooking' in window && 'disableScrollView' in window.ameliaBooking && window.ameliaBooking.disableScrollView === true) { return } this.scrollView('am-button-wrapper-' + this.$root.shortcodeData.counter, 'end') }, unSelectTime () { this.appointment.bookingStartTime = null this.showCalendarContinueButton = false }, refreshCalendar () { let calendarTimeSlots = [] let availableDates = [] for (let dateKey in this.calendarTimeSlots) { for (let timeKey in this.calendarTimeSlots[dateKey]) { for (let slotInfoKey in this.calendarTimeSlots[dateKey][timeKey]) { if (this.appointment.providerId && this.calendarTimeSlots[dateKey][timeKey][slotInfoKey][0] === this.appointment.providerId) { if (!(dateKey in calendarTimeSlots)) { availableDates.push(moment(dateKey).toDate()) calendarTimeSlots[dateKey] = {} } if (!(timeKey in calendarTimeSlots[dateKey])) { calendarTimeSlots[dateKey][timeKey] = [] } calendarTimeSlots[dateKey][timeKey].push(this.calendarTimeSlots[dateKey][timeKey][slotInfoKey]) } } } } this.calendarTimeSlots = calendarTimeSlots this.disabledWeekdays = {weekdays: []} this.disabledWeekdays = (availableDates.length === 0) ? {weekdays: [1, 2, 3, 4, 5, 6, 7]} : null this.availableDates = availableDates this.availableTimeSlots = Object.keys(calendarTimeSlots[moment(this.selectedDate).format('YYYY-MM-DD')]) }, showTimeSlots () { setTimeout(() => { let weeksWrapper = document.getElementsByClassName('c-weeks-rows-wrapper')[0] let weekRow = weeksWrapper.firstChild.children.item(this.selectedWeekIndex) this.times = document.getElementById(this.calendarId) weekRow.parentNode.insertBefore(this.times, weekRow.nextSibling) this.showTimes = true }, 200) }, cancelRecurringSetup () { this.activeRecurringSetup = false let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-recurring-active') this.showTimeSlots() }, confirmRecurringSetup () { let amContainer = document.getElementById(this.id) this.activeRecurringDates = true this.activeRecurringSetup = true amContainer.classList.toggle('am-active-picker', false) amContainer.classList.toggle('am-active-recurring-dates', true) }, cancelRecurringDates () { this.activeRecurringDates = false this.activeRecurringSetup = true let amContainer = document.getElementById(this.id) amContainer.classList.toggle('am-active-picker', true) amContainer.classList.toggle('am-active-confirm', this.activeRecurringDates) amContainer.classList.toggle('am-active-recurring-dates', false) if (this.showCalendarOnly(true)) { amContainer.classList.add('am-mobile-collapsed') amContainer.classList.remove('am-desktop') } }, confirmRecurringDates () { let selectedAppointment = this.recurringData.startAppointment this.selectedProvider = this.getProviderById(selectedAppointment.providerId) this.selectedLocation = this.getLocationById(selectedAppointment.locationId) this.appointment.bookings[0].extras = this.selectedExtras // Customization hook if ('afterBookingSelectDateAndTime' in window) { window.afterBookingSelectDateAndTime(Object.assign(this.appointment, { providerId: selectedAppointment.providerId, locationId: selectedAppointment.locationId }), this.getServiceById(this.appointment.serviceId), this.selectedProvider, this.selectedLocation) } this.activeConfirm = true this.activeRecurringDates = false this.activeRecurringSetup = false let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-active-recurring-dates') amContainer.classList.toggle('am-active-confirm', this.activeConfirm) }, showNextScreen () { this.recurringData.dates = [] if (this.activeRecurring && this.isRecurringAvailable && !this.activeRecurringSetup) { this.loading = true this.recurringData.startDate = this.appointment.bookingStart this.recurringData.startTime = this.appointment.bookingStart.split(' ')[1] let service = this.getServiceById(this.appointment.serviceId) this.initialRecurringData = this.getDefaultRecurringSettings( this.appointment.bookingStart, service.recurringCycle, this.calendarTimeSlots ) setTimeout(() => { let amContainer = document.getElementById(this.id) amContainer.classList.remove('am-show-calendar') this.loading = false this.showTimes = false this.activeRecurringSetup = true }, 500) return } let dateString = moment(this.selectedDate).format('YYYY-MM-DD') if (!this.appointment.providerId) { let employeesIds = this.calendarTimeSlots[dateString][this.appointment.bookingStartTime].map( i => i[0] ).filter( (v, i, a) => a.indexOf(v) === i ) this.appointment.providerId = employeesIds[Math.floor(Math.random() * (employeesIds.length) + 1) - 1] } if (!this.appointment.locationId) { let locationsIds = this.calendarTimeSlots[dateString][this.appointment.bookingStartTime].filter( i => i[0] === this.appointment.providerId ).map(i => i[1]) this.appointment.locationId = locationsIds.length ? this.getPreferredEntityId( this.calendarTimeSlots[dateString], dateString in this.occupiedTimeSlots ? this.occupiedTimeSlots[dateString] : {}, this.appointment.bookingStartTime, this.appointment.providerId, locationsIds, 1 ) : null } this.selectedProvider = this.getProviderById(this.appointment.providerId) this.selectedLocation = this.getLocationById(this.appointment.locationId) this.refreshCalendar() this.appointment.bookings[0].extras = this.selectedExtras // Customization hook if ('afterBookingSelectDateAndTime' in window) { window.afterBookingSelectDateAndTime(this.appointment, this.getServiceById(this.appointment.serviceId), this.getProviderById(this.appointment.providerId), this.getLocationById(this.appointment.locationId)) } this.showConfirmBooking() }, cancelPackageList () { let amContainer = document.getElementById(this.id) this.packageListShown = false this.activePackage = true amContainer.classList.toggle('am-active-picker', true) amContainer.classList.toggle('am-active-package-list', false) }, cancelBooking () { if (this.cacheData) { this.unsetCacheData() let amContainer = document.getElementById(this.id) this.activeConfirm = false amContainer.classList.toggle('am-active-confirm', false) return } if (this.activeRecurring) { let amContainer = document.getElementById(this.id) this.activeRecurringSetup = true this.activeRecurringDates = true this.activeConfirm = false amContainer.classList.toggle('am-active-confirm', false) amContainer.classList.add('am-active-recurring-dates') return } if (this.selectedPackage) { let amContainer = document.getElementById(this.id) this.activeConfirm = false this.activePackage = true if (this.selectedPackage.hasSlots) { this.packageListShown = true this.disableFetchPackageSlots = true amContainer.classList.add('am-active-package-list') } amContainer.classList.toggle('am-active-confirm', false) return } this.activeConfirm = false let amContainer = document.getElementById(this.id) amContainer.classList.toggle('am-active-confirm', this.activeConfirm) if (this.appointment.serviceId && this.appointment.providerId) { amContainer.classList.toggle('am-active-picker', true) } if (this.showCalendarOnly(true)) { amContainer.classList.add('am-mobile-collapsed') amContainer.classList.remove('am-desktop') } }, inlineBookingSVG () { let inlineSVG = require('inline-svg') inlineSVG.init({ svgSelector: 'img.svg-booking', initClass: 'js-inlinesvg' }) }, handleResize () { let amContainer = document.getElementById(this.id) if (this.showCalendarOnly(true) || this.passedPackage) { if (amContainer) { amContainer.classList.add('am-mobile-collapsed') amContainer.classList.remove('am-desktop') } this.showCalendarBackButton = this.options.entities.packages.length > 0 return } if (amContainer) { let amContainerWidth = amContainer.offsetWidth if (this.showCalendarOnly(false) || this.passedPackage) { amContainer.classList.add('am-mobile-collapsed') amContainer.classList.remove('am-desktop') this.showCalendarBackButton = this.options.entities.packages.length > 0 } else { if (amContainerWidth < 670) { amContainer.classList.add('am-mobile-collapsed') amContainer.classList.remove('am-desktop') this.showCalendarBackButton = true } else { amContainer.classList.add('am-desktop') amContainer.classList.remove('am-mobile-collapsed') this.showCalendarBackButton = this.options.entities.packages.length > 0 } } } }, confirmedBooking (responseData, skipNotify, requestData) { this.activeConfirm = false this.bookingCompleted = true this.addToCalendarData = this.getAppointmentAddToCalendarData( responseData, skipNotify ) if (marketingMixin.hasAmeliaTracking(this)) { if (responseData.packageId) { this.marketing.package = responseData.packageId ? this.getPackageById(responseData.packageId) : null } else { this.marketing.service = responseData.appointment.serviceId ? this.getServiceById(responseData.appointment.serviceId) : null this.marketing.employee = responseData.appointment.providerId ? this.getProviderById(responseData.appointment.providerId) : null this.marketing.location = responseData.appointment.locationId ? this.getLocationById(responseData.appointment.locationId) : null this.marketing.category = responseData.appointment.serviceId ? this.getCategoryById(this.marketing.service.categoryId) : null } if (typeof requestData !== 'undefined' && requestData !== null) { this.marketing.payment = requestData.appointment.payment } else { this.marketing.payment = this.appointment.payment } if (this.appointment.payment.gateway === 'onSite') { marketingMixin.trackAmeliaData(this, this.$root.marketing, responseData.type, 'Schedule') } else { marketingMixin.trackAmeliaData(this, this.$root.marketing, responseData.type, 'Purchase') } } // Customization hook if ('beforeConfirmedBooking' in window) { window.beforeConfirmedBooking(this.addToCalendarData) } this.showAddToCalendar = true if (this.showAddToCalendar) { setTimeout(() => { if (!!Object.keys(this.$refs).length && this.$refs.congratulations) { this.$refs.congratulations.$el.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' }) } }, 500) } }, clearValidation () { if (typeof this.$refs.booking !== 'undefined') { this.$refs.booking.clearValidate() } }, closeDialogAddToCalendar () { this.showAddToCalendar = false document.getElementsByClassName('amelia-app-booking')[0].style.display = 'none' window.location.reload() }, resetAppointment () { if (this.$root.shortcodeData.booking.employee) { this.appointment.providerId = this.$root.shortcodeData.booking.employee } if (this.$root.shortcodeData.booking.location) { this.appointment.locationId = this.$root.shortcodeData.booking.location } if (this.$root.shortcodeData.booking.service) { this.appointment.serviceId = this.$root.shortcodeData.booking.service } if (this.$root.shortcodeData.booking.category) { this.appointment.categoryId = this.$root.shortcodeData.booking.category } this.appointment = { bookingStart: '', bookingStartTime: '', bookings: [{ customer: { email: '', externalId: null, firstName: '', id: null, lastName: '', phone: '' }, customFields: {}, customerId: 0, extras: [], persons: 1 }], duration: 0, serviceDuration: 0, group: false, notifyParticipants: this.$root.settings.notifications.notifyCustomers, payment: { amount: 0, gateway: '', currency: '', data: {} }, categoryId: null, providerId: this.forms[this.formType].selectServiceForm.itemsDraggable.employeeFormField.anyEmployeeVisible ? 0 : null, serviceId: this.setServiceIdOnResetAppointment(), locationId: null } this.setBookingCustomFields() }, setServiceIdOnResetAppointment () { if (this.$root.shortcodeData.booking.service) { return this.$root.shortcodeData.booking.service } if (this.passedService && this.passedService.id) { return this.passedService.id } return null }, continuePackage (selectedId) { if (!selectedId) { return false } this.selectedPackageId = selectedId this.selectPackage(this.getPackageById(selectedId)) } }, components: { moment, selectServiceForm, calendarDateTimeForm, recurringSetup, recurringDates, selectPackageForm, packageInfo, packageSetup, packageList, confirmBooking, addToCalendar } } </script>
Save
Back