ID, 'tix_privacy', true ), 'private' ); ?> />
@@ -4662,6 +4675,12 @@ function metabox_attendee_info() {
$rows[] = array( __( 'Edit Token', 'wordcamporg' ), sprintf( '
%s', $this->get_edit_attendee_link( $post->ID, $edit_token ), $edit_token ) );
$rows[] = array( __( 'Access Token', 'wordcamporg' ), sprintf( '
%s', $this->get_access_tickets_link( $access_token ), $access_token ) );
+ $refunds_available_text = __( 'only for organizers', 'wordcamporg' );
+ if ( $this->options['refunds_enabled'] ) {
+ $refunds_available_text = __( 'for attendee', 'wordcamporg' );
+ }
+ $rows[] = array( __( 'Refund Request', 'wordcamporg' ), sprintf( '
Link %s', $this->get_refund_tickets_link( $access_token ), $refunds_available_text ) );
+
// Transaction
$rows[] = array( __( 'Transaction', 'wordcamporg' ), '' );
$rows[] = array( __( 'Payment Method', 'wordcamporg' ), $payment_method );
@@ -5346,7 +5365,7 @@ function template_redirect() {
$this->shortcode_contents = $this->form_access_tickets();
} elseif ( 'edit_attendee' == $tix_action ) {
$this->shortcode_contents = $this->form_edit_attendee();
- } elseif ( 'refund_request' == $tix_action && $this->options['refunds_enabled'] ) {
+ } elseif ( 'refund_request' == $tix_action && ( $this->options['refunds_enabled'] || current_user_can( $this->caps['manage_attendees'] ) ) ) {
$this->shortcode_contents = $this->form_refund_request();
} else {
// If we end up here, start over.
@@ -6348,7 +6367,13 @@ function form_refund_request() {
// Clean things up before and after the shortcode.
$post->post_content = apply_filters( 'camptix_post_content_override', $this->shortcode_str, $post->post_content, $_GET['tix_action'] );
- if ( ! $this->options['refunds_enabled'] || ! isset( $_REQUEST['tix_access_token'] ) || ! ctype_alnum( $_REQUEST['tix_access_token'] ) ) {
+ if ( ! isset( $_REQUEST['tix_access_token'] ) || ! ctype_alnum( $_REQUEST['tix_access_token'] ) ) {
+ $this->error_flags['invalid_access_token'] = true;
+ $this->redirect_with_error_flags();
+ die();
+ }
+
+ if ( ! $this->options['refunds_enabled'] && ! current_user_can( $this->caps['manage_attendees'] ) ) {
$this->error_flags['invalid_access_token'] = true;
$this->redirect_with_error_flags();
die();
@@ -6408,21 +6433,27 @@ function form_refund_request() {
$tickets[$ticket_id] = 1;
}
- if ( count( $transactions ) != 1 || $transactions[ $txn_id ]['payment_amount'] <= 0 ) {
- $this->error_flags['cannot_refund'] = true;
- $this->redirect_with_error_flags();
- die();
- }
+ if ( ! current_user_can( $this->caps['manage_attendees'] ) ) {
+ if ( count( $transactions ) != 1 || $transactions[ $txn_id ]['payment_amount'] <= 0 ) {
+ $this->error_flags['cannot_refund'] = true;
+ $this->redirect_with_error_flags();
+ die();
+ }
- $transaction = array_shift( $transactions );
- if ( ! $transaction['receipt_email'] || ! $transaction['transaction_id'] || ! $transaction['payment_amount'] ) {
- $this->error_flags['cannot_refund'] = true;
- $this->redirect_with_error_flags();
- die();
+ $transaction = array_shift( $transactions );
+ if ( ! $transaction['receipt_email'] || ! $transaction['transaction_id'] || ! $transaction['payment_amount'] ) {
+ $this->error_flags['cannot_refund'] = true;
+ $this->redirect_with_error_flags();
+ die();
+ }
}
// Has a refund request been submitted?
$reason = '';
+ if ( current_user_can( $this->caps['manage_attendees'] ) ) {
+ $reason = wp_sprintf( __( 'In behalf of attendee by %s (%s)', 'wordcamporg' ), wp_get_current_user()->display_name, wp_get_current_user()->user_login );
+ }
+
if ( isset( $_POST['tix_refund_request_submit'] ) ) {
$reason = esc_html( $_POST['tix_refund_request_reason'] );
$check = isset( $_POST['tix_refund_request_confirmed'] ) ? $_POST['tix_refund_request_confirmed'] : false;
@@ -6430,22 +6461,34 @@ function form_refund_request() {
if ( ! $check ) {
$this->error( __( 'You have to agree to the terms to request a refund.', 'wordcamporg' ) );
} else {
+ // Allow organisers to refund tickets without transactions (i.e. free tickets)
+ if ( current_user_can( $this->caps['manage_attendees'] ) && empty( $transactions ) ) {
+ // Change status for all attendees within the same purchase.
+ foreach ( $attendees as $attendee ) {
+ $attendee->post_status = 'refund';
+ wp_update_post( $attendee );
+ }
+
+ // Dumb result in order for checks below to pass, with this we avoid adding new check.
+ $result = CampTix_Plugin::PAYMENT_STATUS_REFUNDED;
+ } else {
+ $payment_method_obj = $this->get_payment_method_by_id( $transaction['payment_method'] );
- $payment_method_obj = $this->get_payment_method_by_id( $transaction['payment_method'] );
+ // Bail if a payment method does not exist.
+ if ( ! $payment_method_obj ) {
+ $this->error_flags['cannot_refund'] = true;
+ $this->redirect_with_error_flags();
+ die();
+ }
- // Bail if a payment method does not exist.
- if ( ! $payment_method_obj ) {
- $this->error_flags['cannot_refund'] = true;
- $this->redirect_with_error_flags();
- die();
- }
+ /**
+ * @todo: Better error messaging for misconfigured payment methods
+ */
- /**
- * @todo: Better error messaging for misconfigured payment methods
- */
+ // Attempt to process the refund transaction
+ $result = $payment_method_obj->payment_refund( $transaction['payment_token'] );
+ }
- // Attempt to process the refund transaction
- $result = $payment_method_obj->payment_refund( $transaction['payment_token'] );
$this->log( 'Individual refund request result.', $attendee->ID, $result, 'refund' );
if ( CampTix_Plugin::PAYMENT_STATUS_REFUNDED == $result ) {
foreach ( $attendees as $attendee ) {