/**
  *    _item_row
  *
  * @param EE_Line_Item $line_item
  * @param array        $options
  * @return mixed
  */
 protected function _item_row(EE_Line_Item $line_item, $options = array())
 {
     $line_item_related_object = $line_item->get_object();
     $parent_line_item_related_object = $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->get_object() : null;
     // start of row
     $row_class = $options['odd'] ? 'item odd' : 'item';
     $html = EEH_HTML::tr('', '', $row_class);
     //Name Column
     $name_link = $line_item_related_object instanceof EEI_Admin_Links ? $line_item_related_object->get_admin_details_link() : '';
     //related object scope.
     $parent_related_object_name = $parent_line_item_related_object instanceof EEI_Line_Item_Object ? $parent_line_item_related_object->name() : '';
     $parent_related_object_name = empty($parent_related_object_name) && $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->name() : $parent_related_object_name;
     $parent_related_object_link = $parent_line_item_related_object instanceof EEI_Admin_Links ? $parent_line_item_related_object->get_admin_details_link() : '';
     $name_html = $line_item_related_object instanceof EEI_Line_Item_Object ? $line_item_related_object->name() : $line_item->name();
     $name_html = $name_link ? '<a href="' . $name_link . '">' . $name_html . '</a>' : $name_html;
     $name_html .= $line_item->is_taxable() ? ' *' : '';
     //maybe preface with icon?
     $name_html = $line_item_related_object instanceof EEI_Has_Icon ? $line_item_related_object->get_icon() . $name_html : $name_html;
     $name_html = '<span class="ee-line-item-name linked">' . $name_html . '</span><br>';
     $name_html .= sprintf(_x('%1$sfor the %2$s: %3$s%4$s', 'eg. "for the Event: My Cool Event"', 'event_espresso'), '<span class="ee-line-item-related-parent-object">', $line_item->parent() instanceof EE_Line_Item ? $line_item->parent()->OBJ_type() : __('Item:', 'event_espresso'), $parent_related_object_link ? '<a href="' . $parent_related_object_link . '">' . $parent_related_object_name . '</a>' : $parent_related_object_name, '</span>');
     $html .= EEH_HTML::td($name_html, '', 'jst-left');
     //Type Column
     $type_html = $line_item->OBJ_type() ? $line_item->OBJ_type() . '<br />' : '';
     $code = $line_item_related_object instanceof EEI_Has_Code ? $line_item_related_object->code() : '';
     $type_html .= !empty($code) ? '<span class="ee-line-item-id">' . sprintf(__('Code: %s', 'event_espresso'), $code) . '</span>' : '';
     $html .= EEH_HTML::td($type_html, '', 'jst-left');
     //Date column
     $datetime_content = '';
     if ($line_item_related_object instanceof EE_Ticket) {
         $datetimes = $line_item_related_object->datetimes();
         foreach ($datetimes as $datetime) {
             if ($datetime instanceof EE_Datetime) {
                 $datetime_content .= $datetime->get_dtt_display_name() . '<br>';
             }
         }
     }
     $html .= EEH_HTML::td($datetime_content, '', 'jst-left');
     //Amount Column
     if ($line_item->is_percent()) {
         $html .= EEH_HTML::td($line_item->percent() . '%', '', 'jst-rght');
     } else {
         $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'jst-rght');
     }
     //finish things off and return
     $html .= EEH_HTML::trx();
     return $html;
 }
 /**
  *    _item_row
  *
  * @param EE_Line_Item $line_item
  * @param array        $options
  * @return mixed
  */
 private function _item_row(EE_Line_Item $line_item, $options = array())
 {
     // start of row
     $row_class = $options['odd'] ? 'item odd' : 'item';
     $html = EEH_HTML::tr('', '', $row_class);
     $obj_name = $line_item->OBJ_type() ? $line_item->OBJ_type() . ': ' : '';
     // name && desc
     $name_and_desc = apply_filters('FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__name', $obj_name . $line_item->name(), $line_item);
     $name_and_desc .= apply_filters('FHEE__EE_SPCO_Line_Item_Display_Strategy__item_row__desc', $options['show_desc'] ? '<span class="line-item-desc-spn smaller-text">: ' . $line_item->desc() . '</span>' : '', $line_item, $options);
     $name_and_desc .= $line_item->is_taxable() ? ' * ' : '';
     // name td
     $html .= EEH_HTML::td($name_and_desc, '', 'item_l');
     // price td
     if ($line_item->is_percent()) {
         $html .= EEH_HTML::td($line_item->percent() . '%', '', 'item_c jst-rght');
     } else {
         $html .= EEH_HTML::td($line_item->unit_price_no_code(), '', 'item_c jst-rght');
     }
     // quantity td
     $html .= EEH_HTML::td($line_item->quantity(), '', 'item_l jst-rght');
     //$total = $line_item->total() * $line_item->quantity();
     $total = $line_item->total();
     if (isset($options['event_id']) && isset($this->_events[$options['event_id']])) {
         $this->_events[$options['event_id']] += $total;
     }
     // total td
     $html .= EEH_HTML::td(EEH_Template::format_currency($total, false, false), '', 'item_r jst-rght');
     // end of row
     $html .= EEH_HTML::trx();
     return $html;
 }
 /**
  * @param EE_Line_Item $line_item
  * @param array        $options
  * @return mixed
  */
 public function display_line_item(EE_Line_Item $line_item, $options = array())
 {
     EE_Registry::instance()->load_helper('HTML');
     $html = '';
     // set some default options and merge with incoming
     $default_options = array('show_desc' => TRUE, 'odd' => FALSE);
     $options = array_merge($default_options, (array) $options);
     switch ($line_item->type()) {
         case EEM_Line_Item::type_line_item:
             // item row
             if ($line_item->OBJ_type() == 'Ticket') {
                 $html .= $this->_ticket_row($line_item);
             } else {
                 $html .= $this->_item_row($line_item);
             }
             // got any kids?
             foreach ($line_item->children() as $child_line_item) {
                 $this->display_line_item($child_line_item);
             }
             break;
         case EEM_Line_Item::type_sub_line_item:
             $html .= $this->_sub_item_row($line_item);
             break;
         case EEM_Line_Item::type_sub_total:
             $text = __('Sub-Total', 'event_espresso');
             if ($line_item->OBJ_type() == 'Event') {
                 if (!isset($this->_events[$line_item->OBJ_ID()])) {
                     $html .= $this->_event_row($line_item);
                     $text = __('Event Sub-Total', 'event_espresso');
                 }
             }
             $count = 0;
             // loop thru children
             foreach ($line_item->children() as $child_line_item) {
                 // recursively feed children back into this method
                 $html .= $this->display_line_item($child_line_item);
                 $count++;
             }
             // only display subtotal if there are multiple child line items
             $html .= $count > 1 ? $this->_sub_total_row($line_item, $text) : '';
             break;
         case EEM_Line_Item::type_tax:
             if ($this->_show_taxes) {
                 $html .= $this->_tax_row($line_item);
             }
             break;
         case EEM_Line_Item::type_tax_sub_total:
             if ($this->_show_taxes) {
                 // loop thru children
                 foreach ($line_item->children() as $child_line_item) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item);
                 }
                 $html .= $this->_total_row($line_item, __('Tax Total', 'event_espresso'), true);
             }
             break;
         case EEM_Line_Item::type_total:
             if (count($line_item->get_items())) {
                 // loop thru children
                 foreach ($line_item->children() as $child_line_item) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item);
                 }
             } else {
                 $html .= $this->_empty_msg_row();
             }
             $html .= $this->_total_row($line_item, __('Total', 'event_espresso'));
             break;
     }
     return $html;
 }
 /**
  * @param EE_Line_Item $line_item
  * @param array        $options
  * @return mixed
  */
 public function display_line_item(EE_Line_Item $line_item, $options = array())
 {
     EE_Registry::instance()->load_helper('HTML');
     $html = '';
     // set some default options and merge with incoming
     $default_options = array('show_desc' => TRUE, 'event_count' => 0);
     $options = array_merge($default_options, (array) $options);
     $options = apply_filters('FHEE__EE_Event_Cart_Line_Item_Display_Strategy__display_line_item__options', $options);
     switch ($line_item->type()) {
         case EEM_Line_Item::type_line_item:
             // item row
             if ($line_item->OBJ_type() == 'Ticket') {
                 $html .= $this->_ticket_row($line_item, $options);
             } else {
                 $html .= $this->_item_row($line_item, $options);
             }
             // got any kids?
             foreach ($line_item->children() as $child_line_item) {
                 $this->display_line_item($child_line_item, $options);
             }
             break;
         case EEM_Line_Item::type_sub_line_item:
             $html .= $this->_sub_item_row($line_item, $options);
             break;
         case EEM_Line_Item::type_sub_total:
             if ($line_item->OBJ_type() == 'Event') {
                 if (!isset($this->_events[$line_item->OBJ_ID()])) {
                     $html .= $this->_event_row($line_item);
                 }
             }
             // loop thru children
             $child_line_items = $line_item->children();
             $count = 0;
             static $total_count = 0;
             foreach ($child_line_items as $child_line_item) {
                 // recursively feed children back into this method
                 $html .= $this->display_line_item($child_line_item, $options);
                 $count += $child_line_item->OBJ_type() == 'Ticket' ? $child_line_item->quantity() : 0;
             }
             $total_count += $line_item->code() != 'pre-tax-subtotal' ? $count : 0;
             //echo "<br>line_item->code: "  . $line_item->code();
             //echo "<br>count: "  . $count;
             //echo "<br>total_count: "  . $total_count;
             // only display subtotal if there are multiple child line items
             if ($line_item->total() > 0 && $count > 1 || $line_item->code() == 'pre-tax-subtotal' && count($child_line_items)) {
                 $count = $line_item->code() == 'pre-tax-subtotal' ? $total_count : $count;
                 $text = __('Subtotal', 'event_espresso');
                 $text = $line_item->code() == 'pre-tax-subtotal' ? EED_Multi_Event_Registration::$event_cart_name . ' ' . $text : $text;
                 apply_filters('FHEE__EE_Event_Cart_Line_Item_Display_Strategy__display_line_item__pretax_subtotal_text', $text, $line_item);
                 $html .= $this->_sub_total_row($line_item, $text, $count);
             }
             break;
         case EEM_Line_Item::type_tax:
             if ($this->_show_taxes) {
                 $this->_taxes_html .= $this->_tax_row($line_item, $options);
             }
             break;
         case EEM_Line_Item::type_tax_sub_total:
             if ($this->_show_taxes) {
                 $child_line_items = $line_item->children();
                 // loop thru children
                 foreach ($child_line_items as $child_line_item) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item, $options);
                 }
                 if (count($child_line_items) > 1) {
                     $this->_taxes_html .= $this->_total_tax_row($line_item, __('Tax Total', 'event_espresso'));
                 }
             }
             break;
         case EEM_Line_Item::type_total:
             // determine whether to display taxes or not
             $this->_show_taxes = $line_item->get_total_tax() > 0 ? true : false;
             if (count($line_item->get_items())) {
                 $options['event_count'] = count($this->_events);
                 // loop thru children
                 foreach ($line_item->children() as $child_line_item) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item, $options);
                 }
             } else {
                 $html .= $this->_empty_msg_row();
             }
             $html .= $this->_taxes_html;
             $html .= $this->_total_row($line_item, apply_filters('FHEE__EE_Event_Cart_Line_Item_Display_Strategy__display_line_item__grand_total_text', EED_Multi_Event_Registration::$event_cart_name . ' ' . __('Total', 'event_espresso')), EE_Registry::instance()->CART->all_ticket_quantity_count());
             break;
     }
     return $html;
 }
 /**
  * Creates a new, unsaved line item, but if it's a ticket line item
  * with a total of 0, or a subtotal of 0, returns null instead
  * @param EE_Line_Item      $line_item
  * @return EE_Line_Item
  */
 public static function non_empty_line_item(EE_Line_Item $line_item)
 {
     if ($line_item->type() === EEM_Line_Item::type_line_item && $line_item->OBJ_type() === 'Ticket' && $line_item->quantity() == 0) {
         return null;
     }
     $new_li_fields = $line_item->model_field_array();
     //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']);
     return EE_Line_Item::new_instance($new_li_fields);
 }
 /**
  *    _process_billable_total
  *
  * @param EE_Line_Item $line_item
  * @return mixed
  */
 private function _is_billable(EE_Line_Item $line_item)
 {
     $billable = 0;
     // is this a ticket ?
     if ($line_item->OBJ_type() == 'Ticket') {
         //echo '<br/><h5 style="color:#2EA2CC;">$line_item->name() : <span style="color:#E76700">' . $line_item->name() . '</span><br/><span style="font-size:9px;font-weight:normal;color:#666">' . __FILE__ . '</span>    <b style="font-size:10px;color:#333">  ' . __LINE__ . ' </b></h5>';
         //echo '<h5 style="color:#2EA2CC;">$line_item->OBJ_ID() : <span style="color:#E76700">' . $line_item->OBJ_ID() . '</span><br/><span style="font-size:9px;font-weight:normal;color:#666">' . __FILE__ . '</span>    <b style="font-size:10px;color:#333">  ' . __LINE__ . ' </b></h5>';
         // is it in the "do not bill" list?
         foreach ($this->_billable as $REG_ID => $TKT_ID) {
             if ($line_item->OBJ_ID() === $TKT_ID) {
                 //echo '<h5 style="color:#2EA2CC;">billable : <span style="color:#E76700">' . $line_item->unit_price() . '</span><br/><span style="font-size:9px;font-weight:normal;color:#666">' . __FILE__ . '</span>    <b style="font-size:10px;color:#333">  ' . __LINE__ . ' </b></h5>';
                 $this->_billable_total += $line_item->unit_price();
                 //$this->_total_items += $line_item->quantity();
                 if ($line_item->is_taxable()) {
                     $this->_billable_tax_total += $line_item->unit_price();
                 }
                 $this->_total_items++;
                 $billable++;
                 unset($this->_do_not_bill[$REG_ID]);
             }
         }
         foreach ($this->_do_not_bill as $REG_ID => $TKT_ID) {
             if ($line_item->OBJ_ID() === $TKT_ID) {
                 //echo '<h5 style="color:#2EA2CC;">non_billable : <span style="color:#E76700">' . $line_item->unit_price() . '</span><br/><span style="font-size:9px;font-weight:normal;color:#666">' . __FILE__ . '</span>    <b style="font-size:10px;color:#333">  ' . __LINE__ . ' </b></h5>';
                 $this->_non_billable_total += $line_item->unit_price();
                 if ($line_item->is_taxable()) {
                     $this->_non_billable_tax_total += $line_item->unit_price();
                 }
                 unset($this->_do_not_bill[$REG_ID]);
             }
         }
     }
     return $billable;
 }
 /**
  *    adjust_SPCO_line_item_display
  *
  *   allows promotions to adjust the line item name in EE_SPCO_Line_Item_Display_Strategy
  *
  * @access    public
  * @param string $line_item_name
  * @param \EE_Line_Item $line_item
  * @return float
  */
 public static function adjust_SPCO_line_item_display($line_item_name, EE_Line_Item $line_item)
 {
     // is this a promotion ?
     if ($line_item->OBJ_type() == 'Promotion') {
         $line_item_name = sprintf(__('Discount: %1$s', 'event_espresso'), $line_item->name());
     }
     return $line_item_name;
 }
 /**
  * @param EE_Line_Item $line_item
  * @param array        $options
  * @return mixed
  */
 public function display_line_item(EE_Line_Item $line_item, $options = array())
 {
     EE_Registry::instance()->load_helper('Template');
     EE_Registry::instance()->load_helper('HTML');
     $html = '';
     // set some default options and merge with incoming
     $default_options = array('show_desc' => true, 'odd' => false);
     $options = array_merge($default_options, (array) $options);
     switch ($line_item->type()) {
         case EEM_Line_Item::type_line_item:
             $this->_show_taxes = $line_item->is_taxable() ? true : $this->_show_taxes;
             if ($line_item->OBJ_type() == 'Ticket') {
                 // item row
                 $html .= $this->_ticket_row($line_item, $options);
                 // got any kids?
                 foreach ($line_item->children() as $child_line_item) {
                     $this->display_line_item($child_line_item, $options);
                 }
             } else {
                 // item row
                 $html .= $this->_item_row($line_item, $options);
                 // got any kids?
                 foreach ($line_item->children() as $child_line_item) {
                     $this->display_line_item($child_line_item, $options);
                 }
             }
             break;
         case EEM_Line_Item::type_sub_line_item:
             $html .= $this->_sub_item_row($line_item, $options);
             break;
         case EEM_Line_Item::type_sub_total:
             static $sub_total = 0;
             $event_sub_total = 0;
             $text = __('Sub-Total', 'event_espresso');
             if ($line_item->OBJ_type() == 'Event') {
                 $options['event_id'] = $event_id = $line_item->OBJ_ID();
                 if (!isset($this->_events[$options['event_id']])) {
                     $event = EEM_Event::instance()->get_one_by_ID($options['event_id']);
                     if ($event instanceof EE_Event) {
                         if ($event->default_registration_status() == EEM_Registration::status_id_not_approved) {
                             return '';
                         }
                     }
                     $this->_events[$options['event_id']] = 0;
                     $html .= $this->_event_row($line_item);
                     $text = __('Event Sub-Total', 'event_espresso');
                 }
             }
             $child_line_items = $line_item->children();
             // loop thru children
             foreach ($child_line_items as $child_line_item) {
                 // recursively feed children back into this method
                 $html .= $this->display_line_item($child_line_item, $options);
             }
             $event_sub_total += isset($options['event_id']) ? $this->_events[$options['event_id']] : 0;
             $sub_total += $event_sub_total;
             if ($line_item->code() != 'pre-tax-subtotal' && count($child_line_items) > 1 || $line_item->code() == 'pre-tax-subtotal' && count($this->_events) > 1) {
                 $options['sub_total'] = $line_item->OBJ_type() == 'Event' ? $event_sub_total : $sub_total;
                 $html .= $this->_sub_total_row($line_item, $text, $options);
             }
             break;
         case EEM_Line_Item::type_tax:
             if ($this->_show_taxes) {
                 $this->_taxes_html .= $this->_tax_row($line_item, $options);
             }
             break;
         case EEM_Line_Item::type_tax_sub_total:
             if ($this->_show_taxes) {
                 $child_line_items = $line_item->children();
                 // loop thru children
                 foreach ($child_line_items as $child_line_item) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item, $options);
                 }
                 if (count($child_line_items) > 1) {
                     $this->_taxes_html .= $this->_total_tax_row($line_item, __('Tax Total', 'event_espresso'), $options);
                 }
             }
             break;
         case EEM_Line_Item::type_total:
             // get all child line items
             $children = $line_item->children();
             // loop thru all non-tax child line items
             foreach ($children as $child_line_item) {
                 if ($child_line_item->type() != EEM_Line_Item::type_tax_sub_total) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item, $options);
                 }
             }
             // now loop thru  tax child line items
             foreach ($children as $child_line_item) {
                 if ($child_line_item->type() == EEM_Line_Item::type_tax_sub_total) {
                     // recursively feed children back into this method
                     $html .= $this->display_line_item($child_line_item, $options);
                 }
             }
             $html .= $this->_taxes_html;
             $html .= $this->_total_row($line_item, __('Total', 'event_espresso'));
             //$html .= $this->_payments_and_amount_owing_rows( $line_item );
             break;
     }
     return $html;
 }