Uname: Linux webm012.cluster130.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Software: Apache
PHP version: 8.0.30 [ PHP INFO ] PHP os: Linux
Server Ip: 145.239.37.162
Your Ip: 216.73.216.190
User: dreampi (1009562) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : appointmentMixin.js
import customFieldMixin from '../../../js/common/mixins/customFieldMixin'
import dateMixin from '../../../js/common/mixins/dateMixin'
import cabinetMixin from '../../frontend/mixins/cabinetMixin'
import paymentMixin from '../../../js/backend/mixins/paymentMixin'

export default {
  mixins: [customFieldMixin, cabinetMixin, dateMixin, paymentMixin],

  data () {
    return {
      recurringAppointments: [],
      customerCreatedCount: 0,
      appointment: null,
      bookings: [],
      duplicateEvent: false,
      exportAction: '',
      exportParams: {
        fields: [
          {label: this.$root.labels.customers, value: 'customers', checked: true},
          {label: this.$root.labels.employee, value: 'employee', checked: true},
          {label: this.$root.labels.service, value: 'service', checked: true},
          {label: this.$root.labels.location, value: 'location', checked: true},
          {label: this.$root.labels.start_time, value: 'startTime', checked: true},
          {label: this.$root.labels.end_time, value: 'endTime', checked: true},
          {label: this.$root.labels.duration, value: 'duration', checked: true},
          {label: this.$root.labels.payment_amount, value: 'paymentAmount', checked: true},
          {label: this.$root.labels.payment_status, value: 'paymentStatus', checked: true},
          {label: this.$root.labels.payment_method, value: 'paymentMethod', checked: true},
          {label: this.$root.labels.price, value: 'price', checked: true},
          {label: this.$root.labels.note, value: 'note', checked: true},
          {label: this.$root.labels.status, value: 'status', checked: true},
          {label: this.$root.labels.custom_fields, value: 'customFields', checked: true},
          {label: this.$root.labels.ph_booking_number_of_persons, value: 'persons', checked: true},
          {label: this.$root.labels.coupon_code, value: 'couponCode', checked: true},
          {label: this.$root.labels.extras, value: 'extras', checked: true}
        ]
      },
      savedAppointment: null,
      totalBookings: 0,
      statuses: [
        {
          value: 'approved',
          label: this.$root.labels.approved

        }, {
          value: 'pending',
          label: this.$root.labels.pending

        },
        {
          value: 'canceled',
          label: this.$root.labels.canceled

        },
        {
          value: 'rejected',
          label: this.$root.labels.rejected

        }
      ],
      noShowStatus: [
        {
          value: 'no-show',
          label: this.$root.labels['no-show']
        }
      ],
      options: {
        fetched: false,
        availableEntitiesIds: {
          packages: [],
          categories: [],
          employees: [],
          locations: [],
          services: []
        },
        entities: {
          categories: [],
          customers: [],
          customFields: [],
          employees: [],
          locations: [],
          services: []
        }
      }
    }
  },

  methods: {
    getInitAppointmentObject (packageCustomer = null) {
      let bookings = []

      if (packageCustomer) {
        let customer = this.options.entities.customers.find(c => c.id === packageCustomer.customerId)

        bookings = [{
          id: 0,
          customer: customer,
          status: this.$root.settings.general.defaultAppointmentStatus,
          duration: null,
          persons: 1,
          total: 0,
          extras: [],
          payments: [],
          price: 0,
          coupon: null,
          added: false,
          visible: true,
          info: JSON.stringify({
            firstName: customer.firstName,
            lastName: customer.lastName,
            email: customer.email,
            phone: customer.phone
          }),
          aggregatedPrice: null,
          packageCustomerService: {
            packageCustomer: {
              id: packageCustomer.id
            }
          },
          customFields: {}
        }]
      }

      return {
        id: 0,
        bookings: bookings,
        categoryId: '',
        serviceId: '',
        providerId: '',
        locationId: '',
        selectedDate: null,
        selectedPeriod: '',
        status: this.$root.settings.general.defaultAppointmentStatus,
        internalNotes: '',
        notifyParticipants: this.$root.settings.notifications.notifyCustomers,
        createPaymentLinks: true,
        dateTimeSlots: [],
        calendarTimeSlots: [],
        occupiedTimeSlots: [],
        bookedTimeSlots: {},
        loadedDates: {},
        extrasTotalPrice: 0,
        serviceTotalPrice: 0,
        discountTotalPrice: 0,
        providerServiceMinCapacity: 0,
        providerServiceMaxCapacity: 0,
        extrasCount: 0,
        extrasSelectedCount: 0,
        duration: 0,
        lessonSpace: 0
      }
    },

    showDialogNewAppointment (packageCustomer = null) {
      this.setBookings(0)

      this.savedAppointment = null

      this.dialogAppointment = true

      setTimeout(() => {
        this.appointment = this.getInitAppointmentObject(packageCustomer)

        if (packageCustomer) {
          this.setBookingCustomFields()
        }
      }, 500)
    },

    showDialogEditAppointment (id, customerId = null) {
      this.dialogAppointment = true

      setTimeout(() => {
        this.getAppointment(id, customerId)
      }, 500)
    },

    saveAppointmentCallback (response, isReassign = false) {
      this.appointment = this.getInitAppointmentObject(null)

      if (response && 'booking' in response && response.booking && !isReassign) {
        this.$http.post(`${this.$root.getAjaxUrl}/bookings/success/` + response.booking.id, {
          type: 'appointment',
          appointmentStatusChanged: response.appointmentStatusChanged,
          paymentId: 'paymentId' in response && response.paymentId ? response.paymentId : null,
          packageBookingFromBackend: 'packageBookingFromBackend' in response ? response.packageBookingFromBackend : null
        })
      }

      this.getAppointmentOptions(true)
    },

    closeDialogAppointment (duplicateEvent = false) {
      this.duplicateEvent = duplicateEvent
      this.dialogAppointment = false
    },

    setBookings (appointmentId) {
      let bookings = []
      let $this = this

      this.options.entities.customers.forEach(function (cusItem) {
        if (cusItem.status !== 'hidden') {
          let bookingId = 0
          let extras = []
          let payments = []
          let coupon = null
          let price = 0
          let duration = null
          let persons = 1
          let aggregatedPrice = null
          let packageCustomerService = null
          let info = JSON.stringify({
            firstName: cusItem.firstName,
            lastName: cusItem.lastName,
            email: cusItem.email,
            phone: cusItem.phone
          })

          if ($this.appointment && appointmentId) {
            $this.appointment.bookings.forEach(function (bookItem) {
              if (bookItem.customerId === cusItem.id) {
                bookingId = bookItem.id
                extras = bookItem.extras
                payments = bookItem.payments
                price = bookItem.price
                duration = bookItem.duration
                persons = bookItem.persons
                coupon = bookItem.coupon
                info = bookItem.info
                aggregatedPrice = bookItem.aggregatedPrice
                packageCustomerService = bookItem.packageCustomerService
              }
            })
          }

          bookings.push({
            id: bookingId,
            customer: cusItem,
            status: $this.$root.settings.general.defaultAppointmentStatus,
            duration: duration,
            persons: persons,
            total: 0,
            extras: extras,
            payments: payments,
            price: price,
            coupon: coupon,
            added: false,
            info: info,
            aggregatedPrice: aggregatedPrice,
            packageCustomerService: packageCustomerService,
            customFields: {}
          })
        }
      })

      this.bookings = bookings
    },

    getAppointment (id, customerId) {
      let config = null

      let timeZone = ''

      if (this.$store !== undefined && this.$store.state.cabinet !== undefined && this.$store.state.cabinet.cabinetType === 'provider') {
        timeZone = this.$store.state.cabinet.timeZone === '' ? 'UTC' : this.$store.state.cabinet.timeZone

        config = Object.assign(this.getAuthorizationHeaderObject(), {params: {source: 'cabinet-' + this.$store.state.cabinet.cabinetType, timeZone: timeZone}})
      }

      if (this.$store === undefined && this.$root.settings.role === 'provider' &&
          this.options.entities.employees.length === 1 && this.options.entities.employees[0].timeZone) {
        config = Object.assign({params: {timeZone: this.options.entities.employees[0].timeZone}})
      }

      this.$http.get(
        `${this.$root.getAjaxUrl}/appointments/` + id,
        config
      )
        .then(response => {
          this.totalBookings = response.data.data.appointment.bookings.length

          if (customerId) {
            response.data.data.appointment.bookings = response.data.data.appointment.bookings.filter(i => parseInt(i.customerId) === parseInt(customerId))
          }

          let $this = this
          this.savedAppointment = JSON.parse(JSON.stringify(response.data.data.appointment))
          this.savedAppointment.categoryId = this.getServiceById(this.savedAppointment.serviceId).categoryId

          this.appointment = Object.assign(this.getInitAppointmentObject(null), response.data.data.appointment)
          this.appointment.notifyParticipants = !!this.appointment.notifyParticipants
          this.appointment.createPaymentLinks = !!this.appointment.createPaymentLinks

          if (timeZone === 'UTC' && this.$root.settings.general.showClientTimeZone) {
            this.appointment.bookingStart = this.getConvertedUtcToLocalDateTime(this.appointment.bookingStart)
            this.appointment.bookingEnd = this.getConvertedUtcToLocalDateTime(this.appointment.bookingEnd)

            this.savedAppointment.bookingStart = this.getConvertedUtcToLocalDateTime(this.savedAppointment.bookingStart)
            this.savedAppointment.bookingEnd = this.getConvertedUtcToLocalDateTime(this.savedAppointment.bookingEnd)
          }

          this.appointment.bookings.forEach(function (bookItem) {
            let serviceExtras = null

            $this.options.entities.services.forEach(function (serItem) {
              if (serItem.id === $this.appointment.serviceId) {
                serviceExtras = JSON.parse(JSON.stringify(serItem.extras))

                serviceExtras.forEach(function (serExtItem) {
                  serExtItem.quantity = 1
                  serExtItem.selected = false
                })
              }
            })

            bookItem.customer = null
            bookItem.added = false

            $this.options.entities.customers.forEach(function (cusItem) {
              if (cusItem.id === bookItem.customerId) {
                bookItem.customer = cusItem

                let customerBookingInfo = $this.getCustomerInfo(bookItem)

                if (bookItem.id !== 0 && customerBookingInfo) {
                  bookItem.info = JSON.stringify({
                    firstName: customerBookingInfo.firstName,
                    lastName: customerBookingInfo.lastName,
                    email: customerBookingInfo.email,
                    phone: customerBookingInfo.phone
                  })
                }

                bookItem.added = true
              }
            })

            bookItem.extras.forEach(function (bookExtItem) {
              serviceExtras.forEach(function (serExtItem) {
                if (serExtItem.extraId === bookExtItem.extraId) {
                  serExtItem.id = bookExtItem.id
                  serExtItem.selected = true
                  serExtItem.quantity = bookExtItem.quantity ? bookExtItem.quantity : 1
                  serExtItem.price = bookExtItem.price
                  serExtItem.aggregatedPrice = bookExtItem.aggregatedPrice
                  serExtItem.tax = bookExtItem.tax
                }
              })
            })

            serviceExtras.forEach(function (serExtItem) {
              if (!serExtItem.selected) {
                serExtItem.id = 0
              }
            })

            bookItem.extras = serviceExtras

            if (bookItem.customFields === '[]' || bookItem.customFields === null) {
              bookItem.customFields = '{}'
            }

            bookItem.customFields = JSON.parse(bookItem.customFields)
          })

          this.setBookings(id)

          this.recurringAppointments = response.data.data.recurring

          this.appointment.lessonSpace = this.appointment.lessonSpace !== null ? this.appointment.lessonSpace.split('https://www.thelessonspace.com/space/')[1] : 0
          if (response.data.data.appointment.lessonSpaceDetails && $this.options.entities.spaces &&
              !$this.options.entities.spaces.find(s => s.id === response.data.data.appointment.lessonSpaceDetails.id)) {
            $this.options.entities.spaces.push(response.data.data.appointment.lessonSpaceDetails)
          }
        })
        .catch(e => {
          console.log(e.message)
        })
    },

    sortBookings (bookings) {
      bookings.sort(function (a, b) {
        return (a.customer.firstName + ' ' + a.customer.lastName).localeCompare((b.customer.firstName + ' ' + b.customer.lastName))
      })
    },

    duplicateAppointmentCallback (appointment) {
      this.appointment = appointment
      this.appointment.id = 0
      this.appointment.selectedDate = null
      this.appointment.selectedPeriod = ''
      this.appointment.dateTimeSlots = []
      this.appointment.calendarTimeSlots = []
      if (this.appointment.bookings[0].packageCustomerService) {
        this.appointment.bookings[0].payments = []
      }
      setTimeout(() => {
        this.dialogAppointment = true
      }, 300)
    },

    getCustomersFromGroup (appointment) {
      let customers = ''

      appointment.bookings.forEach((book) => {
        if (this.options.entities.customers.length) {
          let cus = this.getCustomerInfo(book)

          if (cus) {
            customers += '<span class="am-appointment-status-symbol am-appointment-status-symbol-' + book.status + '"></span><span>' + cus.firstName + ' ' + cus.lastName + '</span><br>'
          }
        }
      })

      return customers
    },

    saveCustomerCallback (response) {
      delete response.user['birthday']

      this.options.entities.customers.push(response.user)

      let service = this.appointment && this.appointment.serviceId ? this.getServiceById(this.appointment.serviceId) : null

      let booking = {
        id: 0,
        customer: response.user,
        customerId: response.user.id,
        status: this.$root.settings.general.defaultAppointmentStatus,
        persons: 1,
        duration: service ? service.duration : null,
        total: 0,
        extras: service ? service.extras : [],
        payments: [],
        coupon: null,
        info: JSON.stringify({
          firstName: response.user.firstName,
          lastName: response.user.lastName,
          email: response.user.email,
          phone: response.user.phone
        }),
        customFields: [],
        added: true
      }

      this.bookings.push(booking)
      this.sortBookings(this.bookings)

      if (this.appointment !== null) {
        this.appointment.bookings.push(booking)
        this.sortBookings(this.appointment.bookings)
      }

      this.setBookingCustomFields()

      this.customerCreatedCount++
    },

    updateAppointmentStatus (app, status, updateCount, callback = null) {
      this.updateStatusDisabled = true

      this.form.post(`${this.$root.getAjaxUrl}/appointments/status/${app.id}`, {
        'status': status,
        'packageCustomerId': 'packageCustomerId' in app && app.packageCustomerId ? app.packageCustomerId : null
      })
        .then(response => {
          let changedBookingsIds = []

          if ('bookingsWithChangedStatus' in response.data) {
            changedBookingsIds = response.data.bookingsWithChangedStatus.map(item => item.id)
          }

          if (updateCount) {
            this.setTotalStatusCounts(app, status, response.data.status, changedBookingsIds)
          }

          this.notify(
            (status === response.data.status) ? this.$root.labels.success : this.$root.labels.error,
            this.$root.labels.appointment_status_changed + (this.$root.labels[response.data.status]).toLowerCase(),
            (status === response.data.status) ? 'success' : 'error'
          )

          app.status = response.data.status

          if ('packageCustomerId' in app && app.packageCustomerId && callback) {
            callback()
          }

          this.updateStatusDisabled = false
        })
        .catch(e => {
          if ('timeSlotUnavailable' in e.response.data.data && e.response.data.data.timeSlotUnavailable === true) {
            this.notify(this.$root.labels.error, this.$root.labels.time_slot_unavailable, 'error')

            app.status = e.response.data.data.status
          }

          this.updateStatusDisabled = false
        })
    },

    updateAppointmentBookingStatus (booking, status, packageCustomer, callback = null) {
      this.updateStatusDisabled = true

      this.form.post(`${this.$root.getAjaxUrl}/bookings/status/${booking.id}`, {
        'status': status
      })
        .then(response => {
          this.notify(
            (status === response.data.booking.status) ? this.$root.labels.success : this.$root.labels.error,
            this.$root.labels.booking_status_changed + (this.$root.labels[response.data.booking.status]).toLowerCase(),
            (status === response.data.booking.status) ? 'success' : 'error'
          )

          booking.status = response.data.booking.status

          if (packageCustomer && callback) {
            callback()
          }

          this.updateStatusDisabled = false
        })
        .catch(e => {
          if ('timeSlotUnavailable' in e.response.data.data && e.response.data.data.timeSlotUnavailable === true) {
            this.notify(this.$root.labels.error, this.$root.labels.time_slot_unavailable, 'error')

            booking.status = e.response.data.data.status
          }

          this.updateStatusDisabled = false
        })
    },

    packageTooltipContent (bookings) {
      let data = this.bookingTypeCountInPackage(bookings)

      let content = ''

      if (data.regular) {
        content += data.regular + '/' + bookings.length + ' ' + this.$root.labels.bookings_regular_tooltip + '<br/>'
      }

      for (let packageId in data.package) {
        let pack = this.getPackageById(parseInt(packageId))

        content += data.package[packageId].count + '/' + bookings.length + ' ' + this.$root.labels.bookings_package_tooltip + ' <strong>' + (pack ? pack.name : 'Package') + '</strong><br/>'
      }

      return content
    },

    deletePaymentCallback (payment) {
      this.updatePaymentCallback(payment, true)
    },

    bookingTypeCountInPackage (bookings) {
      let bookingCountData = {
        regular: 0,
        package: {}
      }

      for (let i = 0; i < bookings.length; i++) {
        if (bookings[i].packageCustomerService !== null) {
          let packageId = bookings[i].packageCustomerService.packageCustomer.packageId

          let payment = bookings[i].packageCustomerService.packageCustomer.payment

          if (packageId in bookingCountData.package) {
            bookingCountData.package[packageId].count++

            bookingCountData.package[packageId].payment += (payment ? payment.ampunt : 0)
          } else {
            bookingCountData.package[packageId] = {
              count: 1,
              price: payment ? payment.amount : 0
            }
          }
        } else {
          bookingCountData.regular++
        }
      }

      return bookingCountData
    },

    getAppointmentPaymentMethods (bookings) {
      let methods = []
      bookings.forEach(function (booking) {
        let method = booking.payments.length ? booking.payments[0].gateway : null
        if (method === '' || method === null) {
          method = 'onSite'
        }
        if (methods.indexOf(method) === -1) {
          methods.push(method)
        }
      })

      return methods
    },

    getAppointmentPayment (bookings) {
      let methods = []
      bookings.forEach((booking) => {
        let method = booking.payments.length ? booking.payments[0] : null
        if (method === null) {
          method = 'onSite'
        }
        let methodExists = methods.find(m => this.getPaymentType(m) === this.getPaymentType(method))
        if (!methodExists) {
          methods.push(method)
        }
      })

      return methods
    },

    editPayment (obj) {
      if (obj.package) {
        let payment = obj.payment
        payment['coupon'] = obj.booking.packageCustomerService.packageCustomer.couponId ? obj.booking.coupon : null

        obj.booking = {
          price: obj.booking.packageCustomerService.packageCustomer.price,
          payments: [payment],
          extras: []
        }
      }

      this.selectedPaymentModalData = this.getPaymentData(obj.payment, obj.package ? null : this.savedAppointment, null, obj.package ? obj : null)

      this.selectedPaymentModalData.customer = this.getCustomerById(obj.payment.customerId)

      this.selectedPaymentModalData.recurring = obj.recurring

      this.dialogPayment = true
    },

    updatePaymentCallback (payment, deleteCallback = false) {
      let $this = this
      this.appointment.bookings.forEach(function (bookingItem) {
        bookingItem.payments.forEach(function (paymentItem, paymentIndex) {
          if (paymentItem.id === payment.id) {
            if (deleteCallback) {
              bookingItem.payments.splice(paymentIndex, 1)
              let index = $this.savedAppointment.bookings.findIndex(b => b.id === bookingItem.id)
              if (index !== -1) {
                $this.savedAppointment.bookings[index].payments.splice(paymentIndex, 1)
              }
            } else {
              bookingItem.payments.splice(paymentIndex, 1, payment)
              let index = $this.savedAppointment.bookings.findIndex(b => b.id === bookingItem.id)
              if (index !== -1) {
                $this.savedAppointment.bookings[index].payments.splice(paymentIndex, 1, payment)
              }
            }
          }
        })
      })

      this.dialogPayment = false
    },

    filterCategoriesByProviderServiceIDs (categories) {
      if (this.currentUser && this.$root.settings.role === 'provider') {
        let providerServiceIDs = this.options.entities.employees.find(e => e.id === this.currentUser.id).serviceList.map(s => s.id)

        const filteredCategories = categories.map(category => {
          if (category.serviceList && category.serviceList.length > 0) {
            const filteredServices = category.serviceList.filter(service => providerServiceIDs.includes(service.id))
            return {
              ...category,
              serviceList: filteredServices
            }
          }
          return category
        }).filter(category => category.serviceList && category.serviceList.length > 0)

        return filteredCategories
      }

      return categories
    }
  },

  watch: {
    'dialogAppointment' () {
      if (this.dialogAppointment === false && this.duplicateEvent === false) {
        this.appointment = null
      }
    }
  }
}
© 2026 GrazzMean-Shell