/**
  * like test_REG_final_price_matches_total_of_filtering_line_item_tree,
  * but makes sure the tickets have sub-prices, because that has shown to have some
  * bugs with calculations so far
  */
 function test_REG_final_price_matches_total_of_filtering_line_item_tree__with_sub_line_items()
 {
     $transaction = $this->new_typical_transaction(array('ticket_types' => 2, 'fixed_ticket_price_modifiers' => 2));
     //add another ticket purchase for one of the same events
     $event1 = EEM_Event::instance()->get_one(array(array('Registration.TXN_ID' => $transaction->ID())));
     $event_line_item = EEM_Line_Item::instance()->get_one(array(array('TXN_ID' => $transaction->ID(), 'OBJ_type' => 'Event', 'OBJ_ID' => $event1->ID())));
     $discount = $this->new_model_obj_with_dependencies('Line_Item', array('LIN_type' => EEM_Line_Item::type_line_item, 'LIN_name' => 'event discount', 'LIN_total' => -8, 'LIN_unit_price' => -8, 'LIN_percent' => 0, 'LIN_quantity' => 1, 'LIN_parent' => $event_line_item->ID(), 'LIN_percent' => null, 'LIN_order' => count($event_line_item->children())));
     $transaction->total_line_item()->recalculate_pre_tax_total();
     //and add an unrelated purchase
     EEH_Line_Item::add_unrelated_item($transaction->total_line_item(), 'Transaction-Wide Discount', -5);
     $totals = EEH_Line_Item::calculate_reg_final_prices_per_line_item($transaction->total_line_item());
     //		honestly the easiest way to confirm the total was right is to visualize the tree
     //		var_dump( $totals );
     //		EEH_Line_Item::visualize( $transaction->total_line_item() );
     //for each registration on the tranasction, verify the REG_final_price
     //indicated by EEH_Line_Item::calculate_reg_final_prices_per_line_item matches
     //what the line item filters would have returned
     EEH_Autoloader::register_line_item_filter_autoloaders();
     foreach ($transaction->registrations() as $registration) {
         $ticket_line_item = EEM_Line_Item::instance()->get_line_item_for_registration($registration);
         $reg_final_price_from_line_item_helper = $totals[$ticket_line_item->ID()];
         //now get the line item filter's final price
         $filters = new EE_Line_Item_Filter_Collection();
         $filters->add(new EE_Single_Registration_Line_Item_Filter($registration));
         $line_item_filter_processor = new EE_Line_Item_Filter_Processor($filters, $transaction->total_line_item());
         $filtered_line_item_tree = $line_item_filter_processor->process();
         $reg_final_price_from_line_item_filter = $filtered_line_item_tree->total();
         $this->assertLessThan(0.2, abs($reg_final_price_from_line_item_filter - $reg_final_price_from_line_item_helper));
     }
 }
 /**
  * Verifies that when we run the line item processor on some line items,
  * that the related real transaction doesn't get modified at all
  */
 function test_process__not_update_transaction()
 {
     $txn = $this->new_typical_transaction(array('ticket_types' => 2));
     $original_total = $txn->total();
     //in order for us to do a good test, let's verify
     $this->assertNotEquals(0, $original_total);
     $this->assertEquals(2, count($txn->registrations()));
     //ok now use the processor with some kind of filter
     $collection = new EE_Line_Item_Filter_Collection();
     $collection->add(new EE_Single_Registration_Line_Item_Filter($txn->primary_registration()));
     $processor = new EE_Line_Item_Filter_Processor($collection, $txn->total_line_item());
     $filtered_line_item_tree = $processor->process();
     //doesn't matter which filter so long as it just changes the grand total line item's total is all
     $this->assertNotEquals($txn->total_line_item()->total(), $filtered_line_item_tree->total());
     //and now verify the transaction wasn't changed in this process
     $this->assertEquals($original_total, $txn->total());
 }
 /**
  * 		generates HTML for the Registration main meta box
  *		@access public
  *		@return void
  */
 public function _reg_details_meta_box()
 {
     EEH_Autoloader::register_line_item_display_autoloaders();
     EEH_Autoloader::register_line_item_filter_autoloaders();
     EE_Registry::instance()->load_Helper('Line_Item');
     $transaction = $this->_registration->transaction() ? $this->_registration->transaction() : EE_Transaction::new_instance();
     $this->_session = $transaction->session_data();
     $filters = new EE_Line_Item_Filter_Collection();
     $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
     $filters->add(new EE_Non_Zero_Line_Item_Filter());
     $line_item_filter_processor = new EE_Line_Item_Filter_Processor($filters, $transaction->total_line_item());
     $filtered_line_item_tree = $line_item_filter_processor->process();
     $this->_template_args['REG_ID'] = $this->_registration->ID();
     $line_item_display = new EE_Line_Item_Display('reg_admin_table', 'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
     $this->_template_args['line_item_table'] = $line_item_display->display_line_item($filtered_line_item_tree, array('EE_Registration' => $this->_registration));
     $attendee = $this->_registration->attendee();
     $this->_template_args['view_transaction_button'] = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction', 'espresso_transactions_view_transaction') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'view_transaction', 'TXN_ID' => $transaction->ID()), TXN_ADMIN_URL), __(' View Transaction'), 'button secondary-button right', 'dashicons dashicons-cart') : '';
     $this->_template_args['resend_registration_button'] = $attendee instanceof EE_Attendee && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'espresso_registrations_resend_registration') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'resend_registration', '_REG_ID' => $this->_registration->ID(), 'redirect_to' => 'view_registration'), REG_ADMIN_URL), __(' Resend Registration'), 'button secondary-button right', 'dashicons dashicons-email-alt') : '';
     $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
     $payment = $transaction->get_first_related('Payment');
     $payment = !$payment instanceof EE_Payment ? EE_Payment::new_instance() : $payment;
     $payment_method = $payment->get_first_related('Payment_Method');
     $payment_method = !$payment_method instanceof EE_Payment_Method ? EE_Payment_Method::new_instance() : $payment_method;
     $reg_status_class = 'status-' . $this->_registration->status_ID();
     $reg_details = array('payment_method' => $payment_method->name(), 'response_msg' => $payment->gateway_response(), 'registration_id' => $this->_registration->get('REG_code'), 'registration_session' => $this->_registration->session_ID(), 'ip_address' => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '', 'user_agent' => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '');
     if (isset($reg_details['registration_id'])) {
         $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
         $this->_template_args['reg_details']['registration_id']['label'] = __('Registration ID', 'event_espresso');
         $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
     }
     if (isset($reg_details['payment_method'])) {
         $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
         $this->_template_args['reg_details']['payment_method']['label'] = __('Most Recent Payment Method', 'event_espresso');
         $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
         $this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
         $this->_template_args['reg_details']['response_msg']['label'] = __('Payment method response', 'event_espresso');
         $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
     }
     $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
     $this->_template_args['reg_details']['registration_session']['label'] = __('Registration Session', 'event_espresso');
     $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
     $this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
     $this->_template_args['reg_details']['ip_address']['label'] = __('Registration placed from IP', 'event_espresso');
     $this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
     $this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
     $this->_template_args['reg_details']['user_agent']['label'] = __('Registrant User Agent', 'event_espresso');
     $this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
     $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'default', 'event_id' => $this->_registration->event_ID()), REG_ADMIN_URL);
     $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
     echo EEH_Template::display_template($template_path, $this->_template_args, TRUE);
 }
 /**
  * add line item filters required for this reg step
  *
  * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
  * 		add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters' ) );
  * so any code that wants to use the same set of filters during the payment options reg step,
  * can apply these filters via the following:
  * 		apply_filters( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() )
  * or to an existing filter collection by passing that instead of instantiating a new collection
  *
  * @param \EE_Line_Item_Filter_Collection $line_item_filter_collection
  * @return \EE_Line_Item_Filter_Collection
  */
 public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
 {
     $line_item_filter_collection->add(new EE_Billable_Line_Item_Filter(EE_Registry::instance()->SSN->checkout()->transaction->registrations(EE_Registry::instance()->SSN->checkout()->reg_cache_where_params)));
     $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
     return $line_item_filter_collection;
 }