import ifPromise from 'onyx-common/ifPromise'
import hasKey from 'onyx-common/hasKey'
import normalizeCurrency from 'onyx-common/normalizeCurrency'
import formatCurrency from 'onyx-common/formatCurrency'
const ZEventsApiEventTickets = ({ prototype }) => {
prototype.mapApiStatus = function (status) {
const statusMap = this.API_STATUS_MAP
if (!hasKey(statusMap, status)) return undefined
return statusMap[status]
}
prototype._checkinPhysicalEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/checkin/physical`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function checkinPhysicalEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {number} payload.credentialsId - credentials to tag the ticket with
* @returns {void}
* @example
*
* checkinPhysicalEventTicket({
* id: 2,
* credentialsId: 894848
* })
*/
prototype.checkinPhysicalEventTicket = function (payload) {
const finalPayload = {
id: payload.id
}
if (hasKey(payload, 'credentialsId')) finalPayload.credentials_id = payload.credentialsId
const raw = ifPromise(payload, () => this._checkinPhysicalEventTicket(finalPayload))
return raw
.catch(error => this.onError('checkinPhysicalEventTicket', error))
}
prototype._checkinVirtualEventTicket = function ({ id }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/checkin/virtual`),
method: 'POST'
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function checkinVirtualEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {void}
* @example
*
* checkinVirtualEventTicket({
* id: 2
* })
*/
prototype.checkinVirtualEventTicket = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._checkinVirtualEventTicket(finalPayload))
return raw
.catch(error => this.onError('checkinVirtualEventTicket', error))
}
prototype._claimEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/claim`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function claimEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {string} payload.giftToken - token needed to claim ticket
* @returns {void}
* @example
*
* claimEventTicket({
* id: 2,
* giftToken: '282828282asdfdsafjalsdfj8'
* })
*/
prototype.claimEventTicket = function (payload) {
const finalPayload = {
id: payload.id,
gift_token: payload.giftToken
}
const raw = ifPromise(payload, () => this._claimEventTicket(finalPayload))
return raw
.catch(error => {
const mapErrors = {
'Ticket is already claimed': 'EVENT_TICKET_ALREADY_CLAIMED'
}
return this.onError('claimEventTicket', error, mapErrors)
})
}
prototype.normalizeClaimEventTicketDetails = function (_data) {
const data = this.normalizeData(_data)
const ret = {
giftedUserEmail: data.gifted_user_email,
ticketType: parseInt(data.type) === 1 ? 'vip' : 'ga',
isExistingAccount: !!data['gifted_email_user_exists?'],
eventData: {
id: data.event.id,
description: data.event.description_plain_text,
descriptionHtml: data.event.description_rich_text,
startDate: data.event.start_date,
endDate: data.event.end_date,
title: data.event.name,
eventImageUrl: data.event.event_image_url,
hasImage: !!data.event.has_image,
promotionalVideoUrl: data.event.embed_code,
learnMoreUrl: data.event.learn_more_url
}
}
return ret
}
prototype._getClaimEventTicketDetails = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/claim`),
method: 'GET',
requestType: 'json',
data: rest
}
return this.fetchWrap(payload)
}
/**
* @typedef {object} EventTicketClaimEvent
* @property {number} id - event id
* @property {string} title - event title
* @property {string} description - event description, plain text
* @property {string} descriptionHtml - event description, html
* @property {string} startDate - event start date
* @property {string} endDate - event end date
* @property {string} eventImageUrl - cover image for event
* @property {string} promotionalVideoUrl - url for promo video, takes precedence over cover image if provided
* @property {boolean} hasImage - eventImageUrl will always return something valid, but does the event have an intentionally added image tied to it?
*/
/**
* @typedef {object} ClaimEventTicketDetails
* @property {string} giftedUserEmail - email address attached to claim
* @property {boolean} isExistingUser - is this email address tied to an existing kwivrr user?
* @property {EventTicketClaimEvent} eventData - EventTicketClaimEvent entity
*/
/**
* @function getClaimEventTicketDetails
* @param {object} payload - The payload
* @param {object} payload.id - The ticket id
* @param {string} payload.giftToken - gift token hash tied to claim event
* @returns {ClaimEventTicketDetails} - getClaimEventTicketDetailsReturn
* @example
*
* getClaimEventTicketDetails({
* id: 123,
* giftToken: 223gfsdfger
* })
*/
prototype.getClaimEventTicketDetails = function (payload) {
const finalPayload = {
id: payload.ticketId,
gift_token: payload.giftToken
}
const raw = ifPromise(payload, () => this._getClaimEventTicketDetails(finalPayload))
return raw
.then(res => this.normalizeClaimEventTicketDetails(res.data))
.catch(error => {
const mapErrors = {
'Invalid gift_token parameter': 'EVENT_TICKET_GIFT_TOKEN_INVALID',
'Ticket is already claimed': 'EVENT_TICKET_ALREADY_CLAIMED'
}
return this.onError('getClaimEventTicketDetails', error, mapErrors)
})
}
prototype._directTransferEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/transfer_direct`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function directTransferEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {number} payload.userId - user to transfer ticket to
* @returns {void}
* @example
*
* directTransferEventTicket({
* id: 2,
* userId: 1503
* })
*/
prototype.directTransferEventTicket = function (payload) {
const finalPayload = {
id: payload.id,
user_id: payload.userId
}
const raw = ifPromise(payload, () => this._directTransferEventTicket(finalPayload))
return raw
.catch(error => this.onError('directTransferEventTicket', error))
}
prototype.normalizeEventTicket = function (_data) {
const data = this.normalizeData(_data)
const ticketState = this.mapApiStatus(data.api_status)
const ret = {
isCheckedIn: !!data.is_checked_in,
ticketState,
currentVipPrice: normalizeCurrency(data.event.vip_ticket_price),
currentGeneralPrice: normalizeCurrency(data.event.general_ticket_price),
id: parseInt(data.id),
orderId: parseInt(data.order_id),
currentTicketHolder: data.ticket_holder.email,
userName: `${data.buyer.firstname} ${data.buyer.lastname}`,
userEmail: data.buyer.email,
refund: 0,
credit: 0,
ticketType: data.type,
qrCode: data.qr_code,
chargeInfo: {
individualCharges: [
{
id: hasKey(data.event_order, 'payment_source') ? data.event_order.payment_source.sourceable.id : -1,
ticketType: data.type,
numTickets: parseInt(data.event_order.event_tickets.length),
ticketTotal: normalizeCurrency(data.event_order.sub_total),
formattedTicketTotal: formatCurrency(normalizeCurrency(data.event_order.sub_total)),
subtotal: normalizeCurrency(data.event_order.sub_total),
formattedSubtotal: formatCurrency(normalizeCurrency(data.event_order.sub_total)),
serviceFee: normalizeCurrency(data.event_order.service_fee),
formattedServiceFee: formatCurrency(normalizeCurrency(data.event_order.service_fee)),
tax: normalizeCurrency(data.event_order.tax_total),
formattedTax: formatCurrency(normalizeCurrency(data.event_order.tax_total)),
total: normalizeCurrency(data.event_order.total_price),
formattedTotal: formatCurrency(normalizeCurrency(data.event_order.total_price)),
purchaseDate: this.normalizeDate(data.purchased_datetime),
paymentDetails: {
nameOnCard: hasKey(data.event_order, 'payment_source') ? data.event_order.payment_source.sourceable.name_on_card : `${data.buyer.firstname} ${data.buyer.lastname}`,
lastFourDigits: hasKey(data.event_order, 'payment_source') ? data.event_order.payment_source.sourceable.last_four : '(credit applied)'
}
}
]
}
}
ret.isVip = ret.ticketType === 'vip'
ret.isGeneral = !ret.isVip
ret.hasVip = ret.currentVipPrice > 0
ret.isActive = this.isActiveTicket(ret)
ret.isTransferred = this.isTransferredTicket(ret)
ret.isCheckInable = this.isCheckInableTicket(ret)
ret.isUncheckInable = this.isUncheckInableTicket(ret)
ret.isUpgradeable = this.isUpgradeableTicket(ret)
ret.isTransferrable = this.isTransferrableTicket(ret)
ret.isReclaimable = this.isReclaimableTicket(ret)
ret.isSetCredentialsable = this.isSetCredentialsableTicket(ret)
ret.isRevokable = this.isRevokableTicket(ret)
ret.isPendingTransfer = this.isPendingTransferTicket(ret)
ret.isRefunded = this.isRefundedTicket(ret)
ret.isParticallyRefunded = this.isPartiallyRefundedTicket(ret)
ret.isRevoked = this.isRevokedTicket(ret)
return ret
}
prototype._getEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}`),
method: 'GET',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
prototype.getEventTicket = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._getEventTicket(finalPayload))
return raw
.then(res => this.normalizeEventTicket(res.data))
.catch(error => this.onError('getEventTicket', error))
}
prototype._reclaimEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/reclaim`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function reclaimEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {void}
* @example
*
* reclaimEventTicket({
* id: 2
* })
*/
prototype.reclaimEventTicket = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._reclaimEventTicket(finalPayload))
return raw
.catch(error => this.onError('reclaimEventTicket', error))
}
prototype.normalizeRevokeEventTicket = function (data) {
const ret = {
refundBreakdown: {
kwivrrCredit: normalizeCurrency(data.refund_breakdown.kwivrr_credit),
...(hasKey(data.refund_breakdown, 'credit_card') ? { creditCard: normalizeCurrency(data.refund_breakdown.credit_card) } : {}),
...(hasKey(data.refund_breakdown, 'echeck') ? { echeck: normalizeCurrency(data.refund_breakdown.echeck) } : {})
}
}
ret.refundBreakdown.totalRefund = ret.refundBreakdown.kwivrrCredit
if (hasKey(data.refund_breakdown, 'credit_card')) ret.refundBreakdown.totalRefund = ret.refundBreakdown.totalRefund + ret.refundBreakdown.creditCard
if (hasKey(data.refund_breakdown, 'echeck')) ret.refundBreakdown.totalRefund = ret.refundBreakdown.totalRefund + ret.refundBreakdown.echeck
if (hasKey(data, 'credit_card')) {
ret.creditCard = {
lastFour: data.credit_card.last_four,
cardType: data.credit_card.type
}
} else if (hasKey(data, 'echeck')) {
ret.echeck = {
lastFour: data.echeck.masked_bank_account_number
}
}
return ret
}
prototype._revokeEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/revoke`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @typedef {object} revokeEventTicketRefundBreakdown
* @property {number} kwivrrCredit - how much refund went to kwivrr credit
* @property {number} totalRefund - how much refund combined across credit and real payments
* @property {number} [creditCard] - if payment used was credit card, this is how much went back to that source.
* @property {number} [echeck] - if payment used was echeck, this is how much went back to that source.
*/
/**
* @typedef {object} echeckRefundBreakdownItem
* @property {number} lastFour - last four of bank account number
*/
/**
* @typedef {object} creditCardRefundBreakdownItem
* @property {number} lastFour - last four of credit card
* @property {string} cardType - card type used (visa/mc/discover/amex)
*/
/**
* @typedef {object} revokeEventTicketReturn
* @property {revokeEventTicketRefundBreakdown} refundBreakdown - how refund was allocated
* @property {creditCardRefundBreakdownItem} [creditCard] - if refund is to credit card, this is the entity
* @property {echeckRefundBreakdownItem} [echeck] - if refund is to echeck, this is the entity
*/
/**
* @function revokeEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {string} [payload.refundType='default'] - none, default, kwivrrCredit
* @returns {revokeEventTicketReturn}
* @example
*
* revokeEventTicket({
* id: 2
* })
*/
prototype.revokeEventTicket = function (payload) {
const finalPayload = {
id: payload.id,
refund_type: payload.refundType ? payload.refundType : 'default'
}
const raw = ifPromise(payload, () => this._revokeEventTicket(finalPayload))
return raw
.then(res => this.normalizeRevokeEventTicket(res.data))
.catch(error => this.onError('revokeEventTicket', error))
}
prototype._getRevokeEventTicketRefundBreakdown = function ({ id }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/revoke`),
method: 'GET'
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function getRevokeEventTicketRefundBreakdown
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {revokeEventTicketReturn}
* @example
*
* getRevokeEventTicketRefundBreakdown({
* id: 2
* })
*/
prototype.getRevokeEventTicketRefundBreakdown = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._getRevokeEventTicketRefundBreakdown(finalPayload))
return raw
.then(res => this.normalizeRevokeEventTicket(res.data))
.catch(error => this.onError('getRevokeTicketRefundBreakdown', error))
}
prototype._transferEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/transfer`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function transferEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {string} payload.email - email address to transfer ticket to
* @returns {void}
* @example
*
* transferEventTicket({
* id: 2,
* email: 'jim.bob@test.com'
* })
*/
prototype.transferEventTicket = function (payload) {
const finalPayload = {
id: payload.id,
email: payload.email
}
const raw = ifPromise(payload, () => this._transferEventTicket(finalPayload))
return raw
.catch(error => this.onError('transferEventTicket', error))
}
prototype._unCheckinEventTicket = function ({ id }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/uncheckin`),
method: 'POST'
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function unCheckinEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {void}
* @example
*
* unCheckinEventTicket({
* id: 2
* })
*/
prototype.unCheckinEventTicket = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._unCheckinEventTicket(finalPayload))
return raw
.catch(error => this.onError('uncheckinEventTicket', error))
}
prototype._getUpgradeEventTicketDetails = function ({ id }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/upgrade`),
method: 'GET'
}
return this.authenticatedFetchWrap(payload)
}
prototype.normalizeUpgradeEventTicketDetails = function (_data) {
const data = this.normalizeData(_data)
const ret = {
vipTicketPrice: normalizeCurrency(data.vip_price),
gaTicketPricePaid: normalizeCurrency(data.general_price),
subtotal: normalizeCurrency(data.sub_total),
serviceFee: normalizeCurrency(data.service_fee),
tax: normalizeCurrency(data.tax_total),
total: normalizeCurrency(data.total_price)
}
ret.formattedVipTicketPrice = formatCurrency(ret.vipTicketPrice)
ret.formattedGaTicketPricePaid = formatCurrency(ret.gaTicketPricePaid)
ret.formattedSubtotal = formatCurrency(ret.subtotal)
ret.formattedServiceFee = formatCurrency(ret.serviceFee)
ret.formattedTax = formatCurrency(ret.tax)
ret.formattedTotal = formatCurrency(ret.total)
return ret
}
/**
* @function getUpgradeEventTicketDetails
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {void}
* @example
*
* getUpgradeEventTicketDetails({
* id: 2
* })
*/
prototype.getUpgradeEventTicketDetails = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._getUpgradeEventTicketDetails(finalPayload))
return raw
.then(res => this.normalizeUpgradeEventTicketDetails(res.data))
.catch(error => this.onError('getUpgradeEventTicketDetails', error))
}
prototype._setEventTicketCredentials = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/set_credentials`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function setEventTicketCredentials
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {number} payload.credentialsId - credentials to assign
* @returns {void} - ticket id
* @example
*
* setEventTicketCredentials({
* id: 1000,
* credentialsId: 292929
* })
*/
prototype.setEventTicketCredentials = function (payload) {
const finalPayload = {
id: payload.id,
credentials_id: payload.credentialsId
}
const raw = ifPromise(payload, () => this._setEventTicketCredentials(finalPayload))
return raw
.catch(error => this.onError('setEventTicketCredentials', error))
}
/**
* @function getTicketIdFromQrCode
* @param {object} payload - The payload
* @param {string} payload.text - text from qr code reader
* @returns {string} - ticket id
* @example
*
* getTicketIdFromQrCode({
* text: scan_ticket_6655
* })
*/
prototype.getTicketIdFromQrCode = function (payload) {
const id = payload.text.split('_')[2]
return id
}
prototype.normalizeEventTicketHistoryEntry = function (_data) {
const data = this.normalizeData(_data)
const ret = {
id: parseInt(data.id),
action: this.mapApiStatus(data.api_status),
actionDate: this.normalizeDate(data.modified_date),
text: data.message
}
return ret
}
prototype._getEventTicketHistory = function ({ id }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/history`),
method: 'GET'
}
return this.authenticatedFetchWrap(payload)
}
/**
* @typedef {object} EventTicketHistoryEntry
* @property {string} action - action happening to ticket, see api_status options
* @property {string} datePerformed - date history event occurred
* @property {string} text - text description of event
*/
/**
* @function getEventTicketHistory
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @returns {EventTicketHistoryEntry[]} entries
* @example
*
* getEventTicketHistory({
* id: 2
* })
*/
prototype.getEventTicketHistory = function (payload) {
const finalPayload = {
id: payload.id
}
const raw = ifPromise(payload, () => this._getEventTicketHistory(finalPayload))
return raw
.then(res => this.normalizeListData(res.data, this.normalizeEventTicketHistoryEntry))
.catch(error => this.onError('getEventTicketHistory', error))
}
prototype._upgradeEventTicket = function ({ id, ...rest }) {
const payload = {
url: this.getUrl(`/api/v1/event_tickets/${id}/upgrade`),
method: 'POST',
requestType: 'json',
data: rest
}
return this.authenticatedFetchWrap(payload)
}
/**
* @function upgradeEventTicket
* @param {object} payload - The payload
* @param {number} payload.id - ticket id
* @param {number} payload.credentialsId - credentials to assign
* @returns {void}
* @example
*
* upgradeEventTicket({
* id: 1000,
* credentialsId: 292929
* })
*/
prototype.upgradeEventTicket = function (payload) {
const finalPayload = {
id: payload.id,
zevents_event_order: {
vip_ticket_count: 1
},
apply_credits: false,
payment: this.normalizePayment(payload.payment, false)
}
const raw = ifPromise(payload, () => this._upgradeEventTicket(finalPayload))
return raw
.catch(error => this.onError('upgradeEventTicket', error))
}
}
export default ZEventsApiEventTickets