/**
  *    _calculate_billable_ticket_quantities_from_registrations
  * compiles a list of EE_Tickets for each event in the passed array
  *
  * @access protected
  * @param EE_Registration[] $registrations
  * @return mixed
  */
 protected function _remove_unbillable_registrations($registrations = array())
 {
     if (!empty($registrations)) {
         // these reg statuses require payment (if event is not free)
         $requires_payment = EEM_Registration::reg_statuses_that_allow_payment();
         foreach ($registrations as $key => $registration) {
             if (!$registration instanceof EE_Registration) {
                 continue;
             }
             // are we billing for this registration at this moment ?
             if (!$registration->owes_monies_and_can_pay($requires_payment) && !($registration->final_price() == 0 && in_array($registration->status_ID(), $requires_payment))) {
                 // not billable. remove it
                 unset($registrations[$key]);
             }
         }
     }
     return $registrations;
 }
 /**
  * owes_monies_and_can_pay
  * whether or not this registration has monies owing and it's' status allows payment
  * @access        public
  * @param array $requires_payment
  * @return bool
  */
 public function owes_monies_and_can_pay($requires_payment = array())
 {
     // these reg statuses require payment (if event is not free)
     $requires_payment = !empty($requires_payment) ? $requires_payment : EEM_Registration::reg_statuses_that_allow_payment();
     if (in_array($this->status_ID(), $requires_payment) && $this->final_price() != 0 && $this->final_price() != $this->paid()) {
         return true;
     } else {
         return false;
     }
 }
 /**
  * update registrations REG_paid field after successful payment and link registrations with payment
  *
  * @param EE_Transaction $transaction
  * @param EE_Payment $payment
  * @param EE_Registration[] $registrations
  * @throws \EE_Error
  */
 public function process_registration_payments(EE_Transaction $transaction, EE_Payment $payment, $registrations = array())
 {
     // only process if payment was successful
     if ($payment->status() !== EEM_Payment::status_id_approved) {
         return;
     }
     //EEM_Registration::instance()->show_next_x_db_queries();
     if (empty($registrations)) {
         // find registrations with monies owing that can receive a payment
         $registrations = $transaction->registrations(array(array('STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), 'REG_final_price' => array('!=', 0), 'REG_final_price*' => array('!=', 'REG_paid', true))));
     }
     // still nothing ??!??
     if (empty($registrations)) {
         return;
     }
     // todo: break out the following logic into a separate strategy class
     // todo: named something like "Sequential_Reg_Payment_Strategy"
     // todo: which would apply payments using the capitalist "first come first paid" approach
     // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy"
     // todo: which would be the socialist "everybody gets a piece of pie" approach,
     // todo: which would be better for deposits, where you want a bit of the payment applied to each registration
     $refund = $payment->is_a_refund();
     // how much is available to apply to registrations?
     $available_payment_amount = abs($payment->amount());
     foreach ($registrations as $registration) {
         if ($registration instanceof EE_Registration) {
             // nothing left?
             if ($available_payment_amount <= 0) {
                 break;
             }
             if ($refund) {
                 $available_payment_amount = $this->process_registration_refund($registration, $payment, $available_payment_amount);
             } else {
                 $available_payment_amount = $this->process_registration_payment($registration, $payment, $available_payment_amount);
             }
         }
     }
     if ($available_payment_amount > 0 && apply_filters('FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', false)) {
         EE_Error::add_attention(sprintf(__('A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', 'event_espresso'), EEH_Template::format_currency($available_payment_amount), implode(', ', array_keys($registrations)), '<br/>', EEH_Template::format_currency($payment->amount())), __FILE__, __FUNCTION__, __LINE__);
     }
 }
 /**
  * Creates a new, unsaved line item from $line_item that factors in the
  * number of billable registrations on $registrations.
  * @param EE_Line_Item      $line_item
  * @return EE_Line_Item
  * @param EE_Registration[] $registrations
  */
 public static function billable_line_item(EE_Line_Item $line_item, $registrations)
 {
     $new_li_fields = $line_item->model_field_array();
     if ($line_item->type() === EEM_Line_Item::type_line_item && $line_item->OBJ_type() === 'Ticket') {
         $count = 0;
         foreach ($registrations as $registration) {
             if ($line_item->OBJ_ID() === $registration->ticket_ID() && in_array($registration->status_ID(), EEM_Registration::reg_statuses_that_allow_payment())) {
                 $count++;
             }
         }
         $new_li_fields['LIN_quantity'] = $count;
     }
     //don't set the total. We'll leave that up to the code that calculates it
     unset($new_li_fields['LIN_ID']);
     unset($new_li_fields['LIN_parent']);
     unset($new_li_fields['LIN_total']);
     return EE_Line_Item::new_instance($new_li_fields);
 }
 /**
  * update registrations REG_paid field after successful payment and link registrations with payment
  *
  * @param EE_Transaction $transaction
  * @param EE_Payment $payment
  * @param EE_Registration[] $registrations
  * @throws \EE_Error
  */
 public function process_registration_payments(EE_Transaction $transaction, EE_Payment $payment, $registrations = array())
 {
     // only process if payment was successful
     if ($payment->status() !== EEM_Payment::status_id_approved) {
         return;
     }
     //EEM_Registration::instance()->show_next_x_db_queries();
     if (empty($registrations)) {
         // find registrations with monies owing that can receive a payment
         $registrations = $transaction->registrations(array(array('STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), 'REG_final_price' => array('!=', 0), 'REG_final_price*' => array('!=', 'REG_paid', true))));
     }
     // still nothing ??!??
     if (empty($registrations)) {
         return;
     }
     // todo: break out the following logic into a separate strategy class
     // todo: named something like "Sequential_Reg_Payment_Strategy"
     // todo: which would apply payments using the capitalist "first come first paid" approach
     // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy"
     // todo: which would be the socialist "everybody gets a piece of pie" approach,
     // todo: which would be better for deposits, where you want a bit of the payment applied to each registration
     $refund = $payment->is_a_refund();
     // how much is available to apply to registrations?
     $available_payment_amount = abs($payment->amount());
     //EEH_Debug_Tools::printr( $available_payment_amount, '$available_payment_amount', __FILE__, __LINE__ );
     foreach ($registrations as $registration) {
         if ($registration instanceof EE_Registration) {
             // nothing left?
             if ($available_payment_amount <= 0) {
                 break;
             }
             if ($refund) {
                 $available_payment_amount = $this->process_registration_refund($registration, $payment, $available_payment_amount);
             } else {
                 $available_payment_amount = $this->process_registration_payment($registration, $payment, $available_payment_amount);
             }
         }
     }
 }