<?php
class NBCreatePDF{
	private $template_setting_option;
    public function __construct()
    {
        $this->template_setting_option = get_option( 'nd_invoice_template_settings', array() );
    }
    function invoice_createPDF($order_id,$type="invoice", $output="D", $path = '', $thanks_download = false) {
        global $wpdb;
        $invoice = $this->invoice_getInvoiceOrder($order_id);
        
        $max_invoice_num = $this->invoice_getMaxInvoiceNumber();
        $max_delivery_num = $this->invoice_getMaxDeliveryNumber();
        
        $invoice_number = 0;
        if($max_invoice_num < 1 || $max_invoice_num < $this->template_setting_option['invoice_number_start'])
            $invoice_number = $max_invoice_num < $this->template_setting_option['invoice_number_start'];
        else
            $invoice_number = $max_invoice_num+1;
        $delivery_number = 0;
        if($max_delivery_num<1 || $max_invoice_num < $this->template_setting_option['delivery_number_start'])
            $delivery_number = $this->template_setting_option['delivery_number_start'];
        else
            $delivery_number = $max_delivery_num+1;
        if(empty($invoice)) {
            $data = array(
                'id_order'			=> $order_id,
                'invoice_number'	=> ($type=="invoice")? $invoice_number: 0,
                'delivery_number'	=> ($type=="delivery")? $delivery_number: 0,
                'invoice_date'		=> ($type=="invoice")?  date("Y-m-d H:i:s"): null,
                'delivery_date'		=> ($type=="delivery")? date("Y-m-d H:i:s"): null,
                'date_add'			=> date("Y-m-d H:i:s"),
                'date_update'		=> date("Y-m-d H:i:s"),
            );
            $format = array(
                '%d', 
                '%d', 
                '%d', 
                '%s', 
                '%s', 
                '%s', 
                '%s', 
            );
            $wpdb->insert("{$wpdb->prefix}netbase_invoice_order", $data, $format);
        } else {
            $data = array(
                'invoice_number'	=> ($type=="invoice")?  (empty($invoice['invoice_number']) ? $invoice_number : $invoice['invoice_number']) : $invoice['invoice_number'],
                'delivery_number'	=> ($type=="delivery")?  (empty($invoice['delivery_number']) ? $delivery_number : $invoice['delivery_number']) : $invoice['delivery_number'],
                'invoice_date'		=> ($type=="invoice")?  (empty($invoice['invoice_date']) ? date('Y-m-d H:i:s') : $invoice['invoice_date']) : $invoice['invoice_date'],
                'delivery_date'		=> ($type=="delivery")?  (empty($invoice['delivery_date']) ? date('Y-m-d H:i:s') : $invoice['delivery_date']) : $invoice['delivery_date'],
                'date_update'		=> date("Y-m-d H:i:s"),
            );
            $format = array(
                '%d', 
                '%d', 
                '%s', 
                '%s', 
                '%s', 
            );
            $where = array("id_order" => absint($order_id));
            $where_format = array('%d');
            $wpdb->update("{$wpdb->prefix}netbase_invoice_order", $data, $where, $format, $where_format); 
            
        }
        $content = $this->invoice_getTemplate($order_id, $type);
		if($thanks_download == false){
			if($this->template_setting_option['pdf_template_debug']==1) { // chế độ debug
                echo '<page size="A4">';
                if(isset($content['header'])){
                    echo '<div style="clear:both;background: #fff;width: 764px;">'.$content['header'].'</div>';
                } else {
                    echo '<div style="clear:both;background: #fff;width: 764px;"></div>';
                }
                if(isset($content['content'])){
                    echo "" . $content['content'] . "";
                }
                if(isset($content['footer'])){
                    echo '<div style="clear:both;background: #fff;width: 764px;">'.$content['footer'].'</div>';
                } else {
                    echo '<div style="clear:both;background: #fff;width: 764px;"></div>';
                }
				echo '</page>';
				exit();
			}
		}
        
        $lang=get_bloginfo("language");        
        if($lang == 'th'){
            $mpdf = new \Mpdf\Mpdf([
                'mode' => 'utf-8',
                'default_font' => 'pridi'
            ]);
        } else{
            $mpdf = new \Mpdf\Mpdf([
                'mode' => 'utf-8',
            ]);

        }
            
        $mpdf->autoLangToFont = true;
        $mpdf->showImageErrors = false;
        if ((int)$content['template_landscape']==1) {
            $mpdf = new \Mpdf\Mpdf(['mode' => 'utf-8', 'format' => 'A4-L']);
        }    
        $mpdf->SetFont('notoSans', '', 12);
        $mpdf->setAutoTopMargin = 'stretch';
        $mpdf->SetHTMLHeader($content['header']);
        $mpdf->setAutoBottomMargin = 'stretch';
        $mpdf->SetHTMLFooter($content['footer']);
        $mpdf->WriteHTML($content['content']);

        
        if (ob_get_level() && ob_get_length() > 0) {
            ob_clean();
        }
        $invoice = $this->invoice_getInvoiceOrder($order_id);
        $filename = '';
        if($type == "invoice")
            $filename = $this->invoice_formatInvoiceNumber($invoice). '.pdf';
        else if($type == "delivery")
            $filename = $this->invoice_formatDeliveryNumber($invoice). '.pdf';
        $mpdf->Output($path.$filename, $output);
        if($output=="F")
            return $filename;
        else return true;
    }
    function invoice_getTemplate($order_id, $type='invoice') {
        //
        global $wpdb;
        $sql = "SELECT * FROM {$wpdb->prefix}netbase_invoice_templates WHERE public=1 AND type='".esc_sql($type)."';";
        $item = $wpdb->get_row($sql, ARRAY_A);
        if(empty($item))
            return '';
        $item['style'] = '<style>
                            '.$item['template_custom_css'].'
                        </style>';
        $item['header'] = $this->invoice_replaceShortcode($item["template_invoice_header"], $order_id, $type);
        $item['content'] = $item['style'] . $this->invoice_replaceShortcode($item["template_invoice_content"], $order_id, $type);
        $item['footer'] = $this->invoice_replaceShortcode($item["template_invoice_footer"], $order_id, $type);
        return $item;
    }
    function invoice_replaceShortcode($html, $order_id, $type='invoice') {
        $html = stripslashes(html_entity_decode ($html));
        $order = wc_get_order($order_id);
        $currency = $order->get_currency();
        $payment_gateway = wc_get_payment_gateway_by_order( $order );
        $line_items          = $order->get_items( apply_filters( 'woocommerce_admin_order_item_types', 'line_item' ) );
        $line_items_fee      = $order->get_items( 'fee' );
        $line_items_shipping = $order->get_items( 'shipping' );
        $html = str_replace("[order_number]",  $order->get_order_number(), $html);
        $html = str_replace("[order_date]",  date_i18n( $this->template_setting_option['date_format'], strtotime( $order->get_date_created() ) ), $html);
        $invoice_info = $this->invoice_getInvoiceOrder($order_id);
        $html = str_replace("[invoice_date]",  date_i18n( $this->template_setting_option['date_format'], strtotime( $invoice_info['invoice_date'] ) ), $html);
        $html = str_replace("[delivery_date]",  date_i18n( $this->template_setting_option['date_format'], strtotime( $invoice_info['delivery_date'] ) ), $html);
        $html = str_replace("[invoice_number]", $this->invoice_formatInvoiceNumber($invoice_info), $html);
        $html = str_replace("[delivery_number]", $this->invoice_formatDeliveryNumber($invoice_info), $html);
        $barcode='<barcode code="'.$this->invoice_formatInvoiceNumber($invoice_info).'" type="C128C" class="barcode" />';
        $html = str_replace("[barcode_invoice_number]", $barcode, $html);
        $payment_method = __( $order->get_payment_method_title(), 'netbase-smart-invoice' );
        if ( !$payment_method && $parent_order_id = wp_get_post_parent_id( $order->get_id() ) ) {
            $payment_method = get_post_meta( $parent_order_id, '_payment_method_title', true );
            $payment_method = __( $payment_method, 'netbase-smart-invoice' );
        }
        $payment_method = __( $payment_method, 'netbase-smart-invoice' );
        $html = str_replace("[order_payment_method]", $payment_method, $html);
        $shipping_method = __($order->get_shipping_method(), 'netbase-smart-invoice');
        $html = str_replace("[order_shipping_method]", $shipping_method, $html);
        $html = str_replace("[order_carrier]", $shipping_method, $html);
        $html = str_replace("[order_shipping_cost]", wc_price( $order->get_total_shipping(), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[order_discounted]",  '-'.wc_price( $order->get_total_discount(), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[order_total]",  wc_price( $order->get_total(), array( 'currency' => $currency ) ), $html);
        $taxes = $order->get_tax_totals();
        
        $order_tax = 0;
        $total_product_tax_rate = '';
        if(!empty($taxes)) {
            foreach($taxes as $code => $tax) {
                $order_tax += $tax->amount;
            }
        }
        $order_tax = WC_Tax::round( $order_tax, wc_get_price_decimals() );
        $html = str_replace("[order_tax]",  wc_price( $order_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[order_total_excl_tax]",  wc_price( $order->get_total() - $order_tax, array( 'currency' => $currency ) ), $html);
        
        
        $html = str_replace("[order_subtotal]",  wc_price( $order->get_subtotal(), array( 'currency' => $currency ) ), $html);
        $order_total_not_discount_excl = $order->get_total_discount() + $order->get_total_shipping() + $order->get_subtotal();
        $html = str_replace("[order_total_not_discount_excl]",  wc_price( $order_total_not_discount_excl, array( 'currency' => $currency ) ), $html);
        $order_total_not_discount_incl = $order_tax + $order->get_total_discount() + $order->get_total_shipping() + $order->get_subtotal();
        $html = str_replace("[order_total_not_discount_incl]",  wc_price( $order_total_not_discount_incl, array( 'currency' => $currency ) ), $html);

        $html = str_replace("[total_voucher_amount_tax_incl]",  wc_price( $order->get_total_discount(false), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_voucher_amount_tax_excl]",  wc_price( $order->get_total_discount(true), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[shipping_cost_excl_tax]",  wc_price( $order->get_shipping_total(), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[shipping_cost_tax_amount]",  wc_price( $order->get_shipping_tax(), array( 'currency' => $currency ) ), $html);
        $html = str_replace("[shipping_cost_incl_tax]",  wc_price( $order->get_shipping_tax() + $order->get_shipping_total(), array( 'currency' => $currency ) ), $html);
        if($order->get_shipping_total() >0)
            $html = str_replace("[shipping_cost_tax_rate]",number_format(($order->get_shipping_tax() *100)/$order->get_shipping_total(), 0). '%', $html);
        else 
            $html = str_replace("[shipping_cost_tax_rate]", "", $html);

        $post = get_post($order->get_id());
        $customer = new WP_User($order->get_customer_id());
        $usermeta = get_user_meta($order->get_customer_id());
        $postmeta = get_post_meta($order->get_id());
        
        $wc_countries = new WC_Countries();
        $countries = $wc_countries->get_countries();
        $wc_countries->load_country_states();
        global $states;
        
        $html = str_replace("[customer_email]", $customer->user_email, $html);
        $html = str_replace("[customer_username]", $customer->user_login, $html);
        $html = str_replace("[customer_nickname]", $customer->user_nicename, $html);
        $html = str_replace("[customer_displayname]", $customer->display_name, $html);
        $html = str_replace("[customer_website]", $customer->user_url, $html);
        $html = str_replace("[customer_firstname]", $usermeta['first_name'][0], $html);
        $html = str_replace("[customer_lastname]", $usermeta['last_name'][0], $html);

        $html = str_replace("[billing_firstname]", $postmeta['_billing_first_name'][0], $html);
        $html = str_replace("[billing_lastname]", $postmeta['_billing_last_name'][0], $html);
        $html = str_replace("[billing_company]", $postmeta['_billing_company'][0], $html);
        $html = str_replace("[billing_address]", $postmeta['_billing_address_1'][0], $html);
        if(isset($postmeta['_billing_address_2'])){
            $html = str_replace("[billing_address_line_2]", $postmeta['_billing_address_2'][0], $html);
        } else {
            $html = str_replace("[billing_address_line_2]", "", $html);
        }
        $html = str_replace("[billing_zipcode]", $postmeta['_billing_postcode'][0], $html);
        $html = str_replace("[billing_city]", $postmeta['_billing_city'][0], $html);
        if(!empty($postmeta['_billing_state'][0]))
            $html = str_replace("[billing_state]", $states[$postmeta['_billing_country'][0]][$postmeta['_billing_state'][0]], $html);
        else
            $html = str_replace("[billing_state]", "", $html);
        
        $html = str_replace("[billing_country]", @$countries[$postmeta['_billing_country'][0]], $html);
        $html = str_replace("[billing_mobile_phone]", $postmeta['_billing_phone'][0], $html);
        $html = str_replace("[billing_email]", $postmeta['_billing_email'][0], $html);
        if(isset($postmeta['_shipping_first_name'])){
            $html = str_replace("[delivery_firstname]", $postmeta['_shipping_first_name'][0], $html);
        } else {
            $html = str_replace("[delivery_firstname]", "", $html);
        }
        if(isset($postmeta['_shipping_last_name'])){
            $html = str_replace("[delivery_lastname]", $postmeta['_shipping_last_name'][0], $html);
        } else {
            $html = str_replace("[delivery_lastname]", "", $html);
        }
        if(isset($postmeta['_shipping_company'])){
            $html = str_replace("[delivery_company]", $postmeta['_shipping_company'][0], $html);
        } else {
            $html = str_replace("[delivery_company]", "", $html);
        }
        if(isset($postmeta['_shipping_address_1'])){
            $html = str_replace("[delivery_address]", $postmeta['_shipping_address_1'][0], $html);
        } else {
            $html = str_replace("[delivery_address]", "", $html);
        }
        if(isset($postmeta['_shipping_address_2'])){
            $html = str_replace("[delivery_address_line_2]", $postmeta['_shipping_address_2'][0], $html);
        } else {
            $html = str_replace("[delivery_address_line_2]", "", $html);
        }
        if(isset($postmeta['_shipping_postcode'])){
            $html = str_replace("[delivery_zipcode]", $postmeta['_shipping_postcode'][0], $html);
        } else {
            $html = str_replace("[delivery_zipcode]", "", $html);
        }
        if(isset($postmeta['_shipping_city'])){
            $html = str_replace("[delivery_city]", $postmeta['_shipping_city'][0], $html);
        } else {
            $html = str_replace("[delivery_city]", "", $html);
        }
        if(!empty($postmeta['_shipping_state'][0])){
            $html = str_replace("[delivery_state]", $states[$postmeta['_shipping_country'][0]][$postmeta['_shipping_state'][0]], $html);
        } else {
            $html = str_replace("[delivery_state]", "", $html);
        }
        $html = str_replace("[delivery_country]", @$countries[$postmeta['_shipping_country'][0]], $html);
        $html = str_replace("[delivery_notes]", $post->post_excerpt, $html);
        $order_notes= '';
        $args = array(
                'post_id'   => $order->get_id(),
                'orderby'   => 'comment_ID',
                'order'     => 'DESC',
                'approve'   => 'approve',
                'type'      => 'order_note'
            );
        remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 );
        $notes = get_comments( $args );
        if ( $notes ) {
            foreach( $notes as $note ) {
                $order_notes.=__('Date: ','netbase-smart-invoice').date_i18n( $this->template_setting_option['date_format'], strtotime( $note->comment_date ) ).'<br />';
                $order_notes.=wptexturize( wp_kses_post( $note->comment_content ) ).'<br />';
            }
        }
        $html = str_replace("[order_notes]", $order_notes, $html);		
        $html = str_replace("[products_list]", $this->invoice_renderProductList($order, $type), $html);		
        $html = str_replace("[tax_table]", $this->invoice_renderTaxTable($order), $html);		
        $html = str_replace("[individual_tax_table]", $this->invoice_renderIndividualTaxTable($order), $html);		
        $html = str_replace("[discount_table]", $this->invoice_tableDiscount($order), $html);		
        $all_tax = $this->invoice_getIndividualTax($order);
        $total_product_excl_tax = 0;
        $total_product_tax_amount = 0;
        $total_product_incl_tax = 0;
        $total_order_excl_tax = 0;
        $total_order_tax_amount = 0;
        $total_order_incl_tax = 0;
        $item_id_checked = array();
        if(!empty($all_tax)) {
            foreach($all_tax as $tax) {
                if($tax['type'] == 'product_tax') {
                    $total_product_excl_tax += in_array($tax['item_id'], $item_id_checked) ? 0 : $tax['total_tax_excl'];
                    $total_product_tax_amount += $tax['total_tax_amount'];
                    $total_product_incl_tax = $total_product_excl_tax + $total_product_tax_amount;
                    
                }
                $total_order_excl_tax += in_array($tax['item_id'], $item_id_checked) ? 0 : $tax['total_tax_excl'];
                $total_order_tax_amount +=$tax['total_tax_amount'];;
                $total_order_incl_tax = $total_order_excl_tax + $total_order_tax_amount;
                if(!in_array($tax['item_id'], $item_id_checked)) {
                    $item_id_checked[] = $tax['item_id'];
                } 
                
            }
        }
        if($total_product_excl_tax >0)
            $total_product_tax_rate = wc_format_decimal(($total_product_tax_amount/$total_product_excl_tax)*100, 0).'%';
        else
            $total_product_tax_rate = 0;

        $html = str_replace("[total_product_excl_tax]",  wc_price( $total_product_excl_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_product_tax_amount]",  wc_price( $total_product_tax_amount, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_product_incl_tax]",  wc_price( $total_product_incl_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_order_excl_tax]",  wc_price( $total_order_excl_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_order_tax_amount]",  wc_price( $total_order_tax_amount, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_order_incl_tax]",  wc_price( $total_order_incl_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[total_product_tax_rate]",$total_product_tax_rate, $html);

        $line_items_fee      = $order->get_fees();
        $order_fee_excl_tax = 0;
        $order_fee_tax_amount = 0;
        $order_fee_incl_tax = 0;
        if(!empty($line_items_fee)) {
            foreach($line_items_fee as $fee_id => $fee_item) {
                $order_fee_excl_tax += $fee_item['line_total'];
                $order_fee_tax_amount += $fee_item['line_tax'];
                $order_fee_incl_tax += $fee_item['line_total'] + $fee_item['line_tax'];
            }
        }
        $html = str_replace("[order_fee_excl_tax]",  wc_price( $order_fee_excl_tax, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[order_fee_tax_amount]",  wc_price( $order_fee_tax_amount, array( 'currency' => $currency ) ), $html);
        $html = str_replace("[order_fee_incl_tax]",  wc_price( $order_fee_incl_tax, array( 'currency' => $currency ) ), $html);
        if($order_fee_excl_tax>0)
            $html = str_replace("[order_fee_tax_rate]",  number_format(($order_fee_tax_amount *100)/$order_fee_excl_tax, 0). '%', $html);
        else
            $html = str_replace("[order_fee_tax_rate]", '', $html);

        $refunds = $order->get_refunds();
        
        $order_total_refunded = 0;
        if(!empty($refunds)) {
            foreach($refunds as $refund ) {
                $order_total_refunded += $refund->get_refund_amount();
            }
        }
        $html = str_replace("[order_total_refunded]",  wc_price( -$order_total_refunded, array( 'currency' => $currency ) ), $html);

        $shipping_methods = $order->get_shipping_methods();
        $pickup_locations_token = '';
        foreach ( $shipping_methods as $shipping_item_id => $shipping_item ) {	
            if ( $shipping_item['method_id'] =='local_pickup_plus' ) {	
                $pickup_location = array( 'id' => '' );
                $formatted_pickup_location = '';

                if ( isset( $shipping_item['pickup_location'] ) && $shipping_item['pickup_location'] ) {
                    $pickup_location = maybe_unserialize( $shipping_item['pickup_location'] );
                    $formatted_pickup_location = WC_Shipping_Local_Pickup_Plus__get_formatted_address_helper( $pickup_location );
                }
                
                if ( $formatted_pickup_location ) {
                    $pickup_locations_token .='<div>'. esc_html( preg_replace( '#<br\s*/?>#i', ', ', $formatted_pickup_location ) ).'</div>';
                }
            }
        }
        $html = str_replace("[pickup_locations]",$pickup_locations_token, $html);
        foreach ( $postmeta as $key => $value ) {
            $html = str_replace("[$key]",$value[0], $html);
        }
        return $html;
    }
    function invoice_tableDiscount($order) {
        $currency = $order->get_currency();
        $coupons = $order->get_items("coupon");
        if(empty($coupons))
            return '';
        $html='
        <table id="table_discount" cellpadding="0" cellspacing="0">
            <thead>
                <tr>
                    <th class="table_discount_title">'.__('Discount','netbase-smart-invoice').'</th>
                </tr>
            </thead>
            <tbody>
        ';
        foreach ($coupons as $coupon) {
            $html.='<tr>';
            $html.='<td class="table_discount_content">';
            $html.=__('Coupon: ','netbase-smart-invoice').$coupon['name'];
            $html.='</td>';
            $html.='<td class="table_discount_content">';
            $html.=wc_price(-$coupon['discount_amount'], array( 'currency' => $currency ) );
            $html.='</td></tr>';
        }
        $html.='</tbody>
        </table>';
        return $html;
        
    }
    function invoice_renderIndividualTaxTable($order) {
        $currency = $order->get_currency();
        $taxGroup = $this->invoice_getIndividualTax($order);
        if(empty($taxGroup)) 
            return '';
        $taxArr=array();
        if(empty($taxGroup))
            return '';
        
        for ($i = 0; $i < count($taxGroup); $i ++) {
            $id_tax = $taxGroup[$i]['rate_id'];
            if (isset($taxArr[$id_tax])) {
                $taxArr[$id_tax]['total_tax_amount']+=$taxGroup[$i]['total_tax_amount'];
                $taxArr[$id_tax]['total_tax_excl']+=$taxGroup[$i]['total_tax_excl'];
                $taxArr[$id_tax]['total_tax_incl']+=$taxGroup[$i]['total_tax_incl'];
            } else {
                $taxArr[$id_tax]=array(
                    'id_tax'=>$taxGroup[$i]['rate_id'],
                    'tax_name'=>$taxGroup[$i]['name'],
                    'tax_rate'=>$taxGroup[$i]['tax_rate'],
                    'total_tax_amount'=>$taxGroup[$i]['total_tax_amount'],
                    'total_tax_excl'=>$taxGroup[$i]['total_tax_excl'],
                    'total_tax_incl'=>$taxGroup[$i]['total_tax_incl'],
                );
            }
            
        }
        $html='
            <table id="table_tax_group_by_id_tax" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <th class="title_tax">'.__('Individual Taxes','netbase-smart-invoice').'</th>
                        
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                ';
        $total_tax_excl = 0;
        $total_tax_amount = 0;
        $total_tax_incl = 0;
        foreach ($taxArr as $tax) {
            $total_tax_excl +=$tax['total_tax_excl'];
            $total_tax_amount +=$tax['total_tax_amount'];
            $total_tax_incl +=$tax['total_tax_incl'];
            $html.='<tr>';
            $html.='<td class="content_tax content_tax_name">'.$tax['tax_name'].'</td>';
            $html.='<td class="content_tax content_tax_subtotal">'.wc_price($tax['total_tax_amount'], array( 'currency' => $currency ) ).'</td>';
            $html.='</tr>';
            
        }
        $html.='<tr>';
        $html.='<td class="total content_tax">'.__('Total','netbase-smart-invoice').'</td>';
        $html.='<td class="total content_tax">'.wc_price($total_tax_amount, array( 'currency' => $currency ) ).'</td>';
        $html.='</tr>';
        $html.='</tbody></table>';
        return $html;
        
    }
    function invoice_renderTaxTable($order) {
        $currency = $order->get_currency();
        $tax_breakdowns = $this->invoice_getIndividualTax($order);
        
        if(empty($tax_breakdowns))
            return '';
        $_tax_breakdowns = array();
        foreach ($tax_breakdowns as $k => $v) {
            if(isset($_tax_breakdowns[$v['item_id']])){
                $_tax_breakdowns[$v['item_id']]['total_tax_excl'] =$v['total_tax_excl'];
                $_tax_breakdowns[$v['item_id']]['total_tax_amount'] +=$v['total_tax_amount'];
                $_tax_breakdowns[$v['item_id']]['total_tax_incl'] = $_tax_breakdowns[$v['item_id']]['total_tax_excl']+$_tax_breakdowns[$v['item_id']]['total_tax_amount'];
                
            }
            else{
                $_tax_breakdowns[$v['item_id']] = $v;
            }
        }
        $tax_breakdowns = $_tax_breakdowns;
        $html='
            <table id="table_tax" cellpadding="0" cellspacing="0">
                <thead>
                    <tr>
                        <th class="table_tax_title">'.__('Tax Detail','netbase-smart-invoice').'</th>
                        <th class="table_tax_title">'.__('Tax %','netbase-smart-invoice').'</th>
                        <th class="table_tax_title">'.__('Pre-Tax Total','netbase-smart-invoice').'</th>
                        <th class="table_tax_title">'.__('Total Tax','netbase-smart-invoice').'</th>
                        <th class="table_tax_title">'.__('Total with Tax','netbase-smart-invoice').'</th>
                    </tr>
                </thead>
                <tbody>';
        
        foreach ($tax_breakdowns as $k => $v) {
            $html.='<tr>
                <td class="table_tax_content">';
                if ($v['type'] == 'product_tax') {
                    $html.=__('Products','netbase-smart-invoice');
                } elseif ($v['type'] == 'shipping_tax') {
                    $html.=__('Shipping','netbase-smart-invoice');
                }elseif ($v['type'] == 'fee_tax') {
                    $html.=__('Fee','netbase-smart-invoice');
                }
            $html .= __('[','netbase-smart-invoice').$v['item_name'].__(']','netbase-smart-invoice');		
            $html.='</td><td class="table_tax_content">';
            $html.=(int) $v['tax_rate'].__('%','netbase-smart-invoice');
            $html.='</td>';
            $html.='<td class="table_tax_content">';
            $html.=wc_price($v['total_tax_excl'], array( 'currency' => $currency ) );
            $html.='</td>';
            $html.='<td class="table_tax_content">';
            $html.=wc_price($v['total_tax_amount'], array( 'currency' => $currency ) );
            $html.='</td>';
            $html.='<td class="table_tax_content">';
            $html.=wc_price($v['total_tax_incl'], array( 'currency' => $currency ) );
            $html.='</td></tr>';
        }
        $html.='</tbody>
        </table>';
        return $html;
        
    }
    function invoice_getIndividualTax($order) {
        $tax_breakdowns = array();
        $classes_options  = wc_get_product_tax_class_options();
        $order_taxes         = $order->get_taxes();
        $_taxes = array();
        if(!empty($order_taxes)) {
            foreach($order_taxes as $key=>$tax) {
                $_taxes[$tax->get_rate_id()] = $tax;
            }
        }
        $order_shipping = $order->get_items( array( 'shipping' ) );
        $_order_shipping = reset($order_shipping);
        if(!empty($order_shipping)) {
            foreach($order_shipping as $item_id => $shipping){
                $tax_data      = wc_tax_enabled() ? maybe_unserialize( isset( $shipping['taxes'] ) ? $shipping['taxes'] : '' ) : array();
                if(!isset($tax_data['total']) || empty($tax_data['total']))
                    continue;			
                
                foreach($tax_data['total'] as $k=>$v) {
                    if(empty($v))
                        continue;
                    $tax_id = $k;
                    $tax_class      = wc_get_tax_class_by_tax_id($tax_id);
                    $tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'netbase-smart-invoice' );
                    $tax_name = $tax_class_name;
                    $taxRate = wc_format_decimal(($v/ $shipping['cost'])*100);
                    
                    $tmp_tax= array(
                        'type' => 'shipping_tax',
                        'item_id' => 'shipping_'.$item_id,
                        'item_name' => $shipping['name'],
                        'name' => $tax_name,
                        'rate_id' => $tax_id,
                        'tax_rate' => $taxRate,
                        'total_tax_excl' => $shipping['cost'],
                        'total_tax_amount' => $v,
                        'total_tax_incl' => $shipping['cost'] + $v,
                    );
                    
                    $tax_breakdowns[] = $tmp_tax;
                }
            }
        }
        
        $products = $order->get_items();

        foreach($products as $item_id=>$pro){
            
            $tax_data      = wc_tax_enabled() ? maybe_unserialize( isset( $pro['line_tax_data'] ) ? $pro['line_tax_data'] : '' ) : array();
            if(!isset($tax_data['total']) || empty($tax_data['total']))
                continue;
            
            foreach($tax_data['total'] as $k=>$v) {
                if(empty($v))
                    continue;
                $tax_id = $k;
                $tax_class = wc_get_tax_class_by_tax_id($tax_id);
                $tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'netbase-smart-invoice' );
                $tax_name = $tax_class_name;
                $taxRate = wc_format_decimal(($v/$pro['line_total'])*100);
                $tmp_tax= array(
                    'type' => 'product_tax',
                    'item_id' => 'product_'.$pro['product_id'],
                    'item_name' => $pro['name'],
                    'name' => $tax_name,
                    'rate_id' => $tax_id,
                    'tax_rate' => $taxRate,
                    'total_tax_excl' => $pro['line_total'],
                    'total_tax_amount' => $v,
                    'total_tax_incl' => $pro['line_total'] + $pro['line_tax'],
                );
                
                $tax_breakdowns[] = $tmp_tax;
            }
            
        }
        
        $line_items_fee      = $order->get_items( 'fee' );
        if(!empty($line_items_fee)) {
            foreach($line_items_fee as $item_id => $fee){
                
                $tax_data      = wc_tax_enabled() ? maybe_unserialize( isset( $fee['line_tax_data'] ) ? $fee['line_tax_data'] : '' ) : array();
                if(!isset($tax_data['total']) || empty($tax_data['total']))
                    continue;
                
                foreach($tax_data['total'] as $k=>$v) {
                    if(empty($v))
                        continue;
                    $tax_id = $k;
                    $tax_class      = wc_get_tax_class_by_tax_id($tax_id);
                    $tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'netbase-smart-invoice' );
                    $tax_name = $tax_class_name;
                    $taxRate = wc_format_decimal(($v / $fee['line_total'])*100);
                    
                    $tmp_tax= array(
                        'type' => 'fee_tax',
                        'item_id' => 'fee_'.$item_id,
                        'item_name' => $fee['name'],
                        'name' => $tax_name,
                        'rate_id' => $tax_id,
                        'tax_rate' => $taxRate,
                        'total_tax_excl' => $fee['line_total'],
                        'total_tax_amount' => $v,
                        'total_tax_incl' => $fee['line_total'] + $fee['line_tax'],
                    );
                    
                    $tax_breakdowns[] = $tmp_tax;
                }
                
            }
        }

        return $tax_breakdowns;
    }

    function invoice_renderProductList($order, $type="invoice") {
        global $wpdb;
        $sql = "SELECT * FROM {$wpdb->prefix}netbase_invoice_templates WHERE public = 1 AND type = '".esc_sql($type)."'";
        $item = $wpdb->get_row($sql, ARRAY_A);
        if(empty($item))
            return '';
        
        $products = $order->get_items( apply_filters( 'woocommerce_admin_order_item_types', 'line_item' ) );
        
        $html_product_list = '
            <table 
            id="product_list_tempalte_invoice" 
            style="width:100%;margin-top:27pt;" 
            cellpadding="0" cellspacing="0">
            
        ';
        $columns_number = $item['columns_number'];
        $columns_title = json_decode($item['item_title_json']);
        $columns_content = json_decode($item['item_key_value_json']);
        $columns_color = json_decode($item['item_title_color_json']);
        $columns_bgcolor = json_decode($item['item_title_background_Json']);
        $html_product_list.="<tr style=''>";
        for ($i = 0; $i < $columns_number; $i++) {
                $html_product_list.=
                "<th style='color:#" . $columns_color[$i] . ";
                background-color:#" . $columns_bgcolor[$i] . ";' class='product_list_title product_list_col_"
                .($i+1)." product_list_title_".($i+1)."'>
                " . $columns_title[$i] . "</th>";
        }
        $html_product_list.="</tr>";
        foreach ($products as $item_id =>$pro) {
            $html_product_list.='<tr>';
            for ($j = 0; $j < $columns_number; $j++) {
                $html_product_list.= $this->invoice_getProductColumn($columns_content[$j], $pro, $j, $order, $item_id);	
            }
            $html_product_list.='</tr>';
            
            $epos = $this->invoice_get_extra_options('', $pro, $order);
            if(!empty($epos)) {
                foreach ($epos as $key => $epo) {
                    $tax_row = $this->invoice_get_tax_row_extra_options ($epo, $order, $item_id, $pro);
                    
                    $html_product_list.='<tr>';
                    for ($j = 0; $j < $columns_number; $j++) {
                        $html_product_list.= $this->invoice_get_extra_options_column($columns_content[$j], $epo, $j, $order, $item_id, $pro, $tax_row);	
                    }
                    $html_product_list.='</tr>';
                }
            }
            $epos = $this->invoice_get_fees_extra_options('', $pro, $order);
            if(!empty($epos)) {
                foreach ($epos as $key => $epo) {
                    $tax_row = $this->invoice_get_tax_row_extra_options ($epo, $order, $item_id, $pro);
                    $html_product_list.='<tr>';
                    for ($j = 0; $j < $columns_number; $j++) {
                        $html_product_list.= $this->invoice_get_extra_options_column($columns_content[$j], $epo, $j, $order, $item_id, $pro, $tax_row, 'fee');	
                    }
                    $html_product_list.='</tr>';
                }
            }
                  
        }
        
        $html_product_list.="</table>";
        return $html_product_list;
    }

    function invoice_get_extra_options_column($column_type, $epo, $j, $order, $item_id, $item, $tax_row, $type = 'normal'){    
        
        $html = "";
        $currency = $order->get_currency();
        
        $tax_name = $tax_row['tax_name'];
        $tax_rate = $tax_row['tax_rate'];
        $tax_amount = $tax_row['tax_amount'];
        $total_tax_amount = $tax_row['total_tax_amount'];
        
        
        switch ($column_type)
        {
            case "p_name":
            case "p_name_custom":
                $html.='<td class="product_list_content product_name product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                if($type == 'fee'){
                    $html.= __('Extra Product Options Fees - Value','netbase-smart-invoice').esc_attr($epo['name'],'netbase-smart-invoice'). ': '. esc_attr($epo['value'],'netbase-smart-invoice');
                }else {
                    $html.= __('Extra Product Options - Value','netbase-smart-invoice').esc_attr($epo['name'],'netbase-smart-invoice'). ': '. esc_attr($epo['value'],'netbase-smart-invoice');
                }	
                $html.='</td>';
                break;
            case "p_sku":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" >';
                $html.=__('-','netbase-smart-invoice');
                $html.='</td>';
                break;
            case "unit_price_ex_tax":
            case "unit_price_in_tax_no_old_price":
            case "unit_price_in_tax_in_old_price":
            case "unit_price_ex_tax_has_discount":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'">';
                if(empty($item['item_meta']['tm_has_dpd']) && empty($item['item_meta']['_tm_has_dpd'])){
                    if ($epo['quantity'] <=0){
                        $html.= '<div class="view">'.wc_price( 0, array( 'currency' => $currency ) ).'</div>';
                    }else{
                        $html.= '<div class="view">'.wc_price( $epo['price']/$epo['quantity'], array( 'currency' => $currency ) ).'</div>';    
                    }
                }else{
                    $html.= __('-','netbase-smart-invoice');
                }
                $html.='</td>';
                break;
            
            case "p_tax":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" 
                >';
                $html.= $tax_amount;
                $html.='</td>';
                break;
            case "discounted":
                $html.='<td align="center" class="product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html.= __('-','netbase-smart-invoice');
                $html.='</td>';
                break;
            case "qty":
                $html.='<td class="product_list_content content_QTY product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html.= $epo['quantity'] * (float) $item['item_meta']['_qty'][0];
                $html.= ' ('.$epo['quantity'].'&times;'.(float) $item['item_meta']['_qty'][0].')';
                $html.='</td>';
                break;
            case "total_in_tax":
            case "total_incl_tax_has_discount":
                $html.='<td class="product_list_content product_total product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                if(empty($item['item_meta']['tm_has_dpd']) && empty($item['item_meta']['_tm_has_dpd'])){
                    $html.= wc_price(  (float) $epo['price'] * (float) $item['item_meta']['_qty'][0] + $total_tax_amount, array( 'currency' => $currency ) );
                }else{
                    echo "&nbsp;";
                }
                $html.='</td>';
                break;
            case "p_image":
                $html.='<td class="product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html.='</td>';
                break;
            case "tax_rate":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" >';
                $html.= $tax_rate;
                $html.='</td>';
                break;
            case "total_ex_tax":
            case "total_ex_tax_has_discount":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'">';
                if(empty($item['item_meta']['tm_has_dpd']) && empty($item['item_meta']['_tm_has_dpd'])){
                    $html.= wc_price(  (float) $epo['price'] * (float) $item['item_meta']['_qty'][0], array( 'currency' => $currency ) );
                }else{
                    echo "&nbsp;";
                }
                $html.='</td>';
                break;
            case "tax_name":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $html.= $tax_name;
                $html.='</td>';
                break;
            case "p_desc":
            case "p_shor_desc":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $html.='</td>';
                break;
        }
        return $html;
    }
    function invoice_getProductColumn($column_type, $product, $j, $order, $item_id){    
        $html = "";
        $_product  = $order->get_product_from_item( $product );
        $item_meta = wc_get_order_item_meta($item_id, '');
        $postmeta = get_post_meta($_product->get_id());
        $currency = $order->get_currency();
        $taxes = (array) $order->get_items("tax");
        $_taxes = array();
        if(!empty($taxes)) {
            foreach($taxes as $key=>$tax) {
                $_taxes[$tax->get_rate_id()] = $tax;
            }
        }
        $taxes = $_taxes;
        switch ($column_type)
        {
            case "p_name":
                $html.='<td class="product_list_content product_name product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html.= esc_attr($product['name'],'netbase-smart-invoice');
                $html.='</td>';
                break;
            case "p_name_custom":
                $html.='<td class="product_list_content product_name product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $variants = '';
                if ( $metadata = order_has_meta( $item_id ) ) {
                    
                    foreach ( $metadata as $meta ) {

                        if ( in_array( $meta['meta_key'], apply_filters( 'woocommerce_hidden_order_itemmeta', array(
                            '_qty',
                            '_tax_class',
                            '_product_id',
                            '_variation_id',
                            '_line_subtotal',
                            '_line_subtotal_tax',
                            '_line_total',
                            '_line_tax',
                            'method_id',
                            'cost'
                        ) ) ) ) {
                            continue;
                        }

                        if ( is_serialized( $meta['meta_value'] ) ) {
                            continue;
                        }

                        if ( taxonomy_exists( wc_sanitize_taxonomy_name( $meta['meta_key'] ) ) ) {
                            $term               = get_term_by( 'slug', $meta['meta_value'], wc_sanitize_taxonomy_name( $meta['meta_key'] ) );
                            $meta['meta_key']   = wc_attribute_label( wc_sanitize_taxonomy_name( $meta['meta_key'] ) );
                            $meta['meta_value'] = isset( $term->name ) ? $term->name : $meta['meta_value'];
                        } else {
                            $meta['meta_key']   = wc_attribute_label( $meta['meta_key'], $_product );
                        }
                        
                        $variants.='<span>' . wp_kses_post( rawurldecode( $meta['meta_key'] ) ) . ': </span>' . wp_kses_post( rawurldecode( $meta['meta_value'] ) );
                        $variants.='<br />';
                    }
                    
                }
                if(empty($variants))
                    $html.= esc_attr($product['name'],'netbase-smart-invoice');
                else{
                    $html.= '<strong>'.esc_attr($product['name'],'netbase-smart-invoice').'</strong>';
                    $html.= '<br />';
                    $html.= $variants;
                }
                $html.='</td>';
                break;
            case "p_sku":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" >';
                if ( $_product && $_product->get_sku() ) {
                    $html.=esc_html( $_product->get_sku() );
                }else{
                    $html.=__('-','netbase-smart-invoice');
                }
                $html.='</td>';
                break;
            case "unit_price_ex_tax":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'">';
                $html .= wc_price($item_meta['_line_subtotal'][0]/$item_meta['_qty'][0], array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "unit_price_in_tax_no_old_price":
                $html.='<td class="product_list_content product_price_without_old_price product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" 
                >';
                $html .= wc_price(($item_meta['_line_subtotal'][0]+$item_meta['_line_subtotal_tax'][0])/$item_meta['_qty'][0], array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "p_tax":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" 
                >';
                $html .= wc_price($item_meta['_line_tax'][0]/$item_meta['_qty'][0], array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "discounted":
                $html.='<td align="center" class="product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $discounted = wc_format_decimal( $order->get_item_subtotal( $product, false, false ) - $order->get_item_total( $product, false, false ));
                if($discounted>0){
                    $html .= '-' . wc_price( $discounted, array( 'currency' => $currency ) );
                }else{
                    $html .= '-' ;
                }
                $html.='</td>';
                break;
            case "qty":
                $html.='<td class="product_list_content content_QTY product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html .= $item_meta['_qty'][0];
                $html.='</td>';
                break;
            case "total_in_tax":
                $html.='<td class="product_list_content product_total product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $html .=  wc_price( $item_meta['_line_subtotal'][0]+$item_meta['_line_subtotal_tax'][0], array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "p_image":
                $html.='<td class="product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'" >';
                $thumbnail = $_product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $_product->get_image(  array(48,48,false), array( 'title' => '' ), true ), $item_id, $product ) : '';
                $thumbnail = str_replace('src="//', 'src="http://', $thumbnail);
                $thumbnail = str_replace("src='//", "src='http://", $thumbnail);
                $html.="<div style='width:98px;'>".$thumbnail."</div>";
                $html.='</td>';
                break;
            case "tax_rate":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" >';
                $taxRate = wc_format_decimal(($item_meta['_line_tax'][0] / $item_meta['_line_total'][0])*100,2, true);
                $html .= $taxRate."%";
                $html.='</td>';
                break;
            case "unit_price_in_tax_in_old_price":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'" >';
                $unit_price_tax_incl = ($item_meta['_line_subtotal'][0]+$item_meta['_line_subtotal_tax'][0])/$item_meta['_qty'][0];
                $productPriceOld = $postmeta['_regular_price'][0];
                
                if ($productPriceOld>$unit_price_tax_incl) {
                    $html.="<span style='text-decoration: line-through;'>"
                        .wc_price( $productPriceOld, array( 'currency' => $currency ) )
                        .'</span><br/>';
                }
                
                $html.="<span>".wc_price( $unit_price_tax_incl, array( 'currency' => $currency ) ).'</span>';
                $html.='</td>';
                break;
            case "total_ex_tax":
                $html.='<td class="product_list_content product_list_content_'.($j+1).' product_list_col_'.($j+1).'">';
                $html .=  wc_price( $item_meta['_line_subtotal'][0], array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "tax_name":
                
                $tax_data      = wc_tax_enabled() ? maybe_unserialize( isset( $product['line_tax_data'] ) ? $product['line_tax_data'] : '' ) : array();
                
                $tax_name =array();
                $order_taxes         = $order->get_taxes();
                $classes_options  = wc_get_product_tax_class_options();
                foreach($tax_data['total'] as $tax_id=>$tax) {
                    if(empty($tax)) continue;
                    $tax_class      = wc_get_tax_class_by_tax_id($tax_id);
                    $tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'netbase-smart-invoice' );
                    $tax_name[] = $tax_class_name;
                }
                $tax_name = implode(',', $tax_name);
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $html .= $tax_name;
                $html.='</td>';
                break;
            case "unit_price_ex_tax_has_discount":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $unit_price_ex_tax_has_discount=$item_meta['_line_total'][0]/$item_meta['_qty'][0];
                $html .= wc_price( $unit_price_ex_tax_has_discount, array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "unit_price_in_tax_has_discount":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $unit_price_in_tax_has_discount=($item_meta['_line_total'][0] + $item_meta['_line_tax'][0])/$item_meta['_qty'][0];
                $html .= wc_price( $unit_price_in_tax_has_discount, array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "total_ex_tax_has_discount":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $total_ex_tax_has_discount=$item_meta['_line_total'][0];
                $html .= wc_price( $total_ex_tax_has_discount, array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "total_incl_tax_has_discount":
                $html.='<td class="total_incl_tax_has_discount product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $total_incl_tax_has_discount=$item_meta['_line_total'][0] + $item_meta['_line_tax'][0];
                $html .= wc_price( $total_incl_tax_has_discount, array( 'currency' => $currency ) );
                $html.='</td>';
                break;
            case "p_desc":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $html .= $_product->post->post_content;
                $html.='</td>';
                break;
            case "p_shor_desc":
                $html.='<td class="product_tax_name product_list_content product_list_content_'.($j+1)
                .' product_list_col_'.($j+1).'">';
                $html .= $_product->post->post_excerpt;
                $html.='</td>';
                break;
        }
        return $html;
    }
    /********** get Fees from Extra options *****************/
    function invoice_get_fees_extra_options($item_id="", $item=array(), $order) {
        if(is_plugin_active('woocommerce-tm-extra-product-options/tm-woo-extra-product-options.php') == false)
            return false;
        ////////////
        $epos = array();
        $has_fee = is_array($item)
                && isset($item['item_meta']) 
                && isset($item['item_meta']['_tmcartfee_data']) 
                && isset($item['item_meta']['_tmcartfee_data'][0]);

        if ($has_fee){
            $current_product_id=$item['product_id'];
            $original_product_id = floatval(TM_EPO_WPML()->get_original_id( $current_product_id,'product' ));
            if (TM_EPO_WPML()->get_lang()==TM_EPO_WPML()->get_default_lang() && $original_product_id!=$current_product_id){
                $current_product_id = $original_product_id;
            }
            $wpml_translation_by_id=TM_EPO_WPML()->get_wpml_translation_by_id( $current_product_id );
        }
        if ($has_fee){
            $epos = maybe_unserialize($item['item_meta']['_tmcartfee_data'][0]);
            if (isset($epos[0])){
                $epos = $epos[0];               
            }else{
                $epos = false;
            }

            if ($epos && is_array($epos) && !empty($epos[0])){

                foreach ($epos as $key => $epo) {
                    if ($epo && is_array($epo)){
                        if(!isset($epo['quantity'])){
                            $epo['quantity'] = 1;
                        }
                        if(isset($wpml_translation_by_id[$epo['section']])){
                            $epo['name'] = $wpml_translation_by_id[$epo['section']];
                        }
                        if(isset($wpml_translation_by_id["options_".$epo['section']]) && is_array($wpml_translation_by_id["options_".$epo['section']]) && !empty($epo['multiple']) && !empty($epo['key'])){
                            $pos = strrpos($epo['key'], '_');
                            if($pos!==false) {
                                $av=array_values( $wpml_translation_by_id["options_".$epo['section']] );
                                if (isset($av[substr($epo['key'], $pos+1)])){
                                    $epo['value'] = $av[substr($epo['key'], $pos+1)];
                                    if (!empty($epo['use_images']) && !empty($epo['images']) && $epo['use_images']=="images"){
                                        $epo['value'] ='<div class="cpf-img-on-cart"><img alt="" class="attachment-shop_thumbnail wp-post-image epo-option-image" src="'.apply_filters("tm_image_url",$epo['images']).'" /></div>'.$epo['value'];
                                    }
                                }
                            }
                        }

                        $epo_name = apply_filters('tm_translate',$epo['name']);
                        $epo_value = apply_filters('tm_translate',$epo['value']);
                        $epo_quantity = ( $epo['quantity'] * (float) $item['item_meta']['_qty'][0] ).' <small>('.$epo['quantity'].'&times;'.(float) $item['item_meta']['_qty'][0].')</small>';
                        
                    }
                }
            }
        }
        return $epos;
    }
    function invoice_get_tax_row_extra_options($epo, $order, $item_id, $item) {
        if(is_plugin_active('woocommerce-tm-extra-product-options/tm-woo-extra-product-options.php') == false)
                return false;
        $currency = $order->get_currency();
        $tax_data      = empty( $legacy_order ) && wc_tax_enabled() ? maybe_unserialize( isset( $item['line_tax_data'] ) ? $item['line_tax_data'] : '' ) : false;
        $tax_name = array();
        $tax_rate = array();
        $tax_amount = array();
        $total_tax_amount = 0;
        $order_taxes = $order->get_taxes();
        if ( ! empty( $tax_data ) ) {
            $tax_based_on       = get_option( 'woocommerce_tax_based_on' );
            if ( 'billing' === $tax_based_on ) {
                $country  = $order->billing_country;
                $state    = $order->billing_state;
                $postcode = $order->billing_postcode;
                $city     = $order->billing_city;
            } elseif ( 'shipping' === $tax_based_on ) {
                $country  = $order->shipping_country;
                $state    = $order->shipping_state;
                $postcode = $order->shipping_postcode;
                $city     = $order->shipping_city;
            }

            if ( 'base' === $tax_based_on || empty( $country ) ) {
                $default  = wc_get_base_location();
                $country  = $default['country'];
                $state    = $default['state'];
                $postcode = '';
                $city     = '';
            }
            $tax_class         = $item['tax_class'];
            $tax_rates = WC_Tax::find_rates( array(
                    'country'   => $country,
                    'state'     => $state,
                    'postcode'  => $postcode,
                    'city'      => $city,
                    'tax_class' => $tax_class
                ) );
            $epo_line_taxes = WC_Tax::calc_tax( (float) $epo['price'] * (float) $item['item_meta']['_qty'][0], $tax_rates, false );
            
            foreach ( $order_taxes as $tax_item ) {
                if (isset($epo_line_taxes[$tax_item['rate_id']])){
                    $tax_price = $epo_line_taxes[$tax_item['rate_id']];
                    
                    $tax_rate[] = absint($tax_rates[$tax_item['rate_id']]['rate']).'%';
                    $tax_amount[] =  wc_price( wc_round_tax_total( $tax_price ), array( 'currency' => $currency ) );
                    $tax_name[] =  $tax_rates[$tax_item['rate_id']]['label'];
                    $total_tax_amount +=$tax_price;
                }		
            }
        }
        
        return array(
            'tax_name' => implode(',', $tax_name),
            'tax_rate' => implode(',', $tax_rate),
            'tax_amount' => implode(',', $tax_amount),
            'total_tax_amount' => $total_tax_amount
        );
    }
    function invoice_checkOrderStatus($order) {
        $option = $this->template_setting_option['nb_order_status_wc-'.$order->get_status()];
        if($option == 1)
            return true;
        return false;
    }
    function invoice_customer_can_download($order) {
        $customer_download = $this->template_setting_option['customer_can_download_pdf'];
        $download_order_status = [];
        if(isset($this->template_setting_option['customer_download_invoice_status'])){
            $download_order_status = $this->template_setting_option['customer_download_invoice_status'];
        }
        $can_download = false;
        switch ($customer_download) {
            case 'available':
                $invoice_info = $this->invoice_getInvoiceOrder($order->get_id());
                if(!isset($invoice_info['invoice_date']) || empty($invoice_info['invoice_date']))
                    $can_download = false;
                else
                    $can_download = true;
                break;
            case 'always':
                $can_download = true;
                break;
            case 'never':
                $can_download = false;
                break;
            case 'option':
                if(count($download_order_status) > 0){
                    if (in_array( 'wc-'.$order->get_status(), array_keys($download_order_status) ) ) {
                        $can_download = true;
                    }
                } else {
                    $can_download = false;							
                }
                break;
        }
        return $can_download;
    }
    function invoice_get_extra_options($item_id="", $item=array(), $order){
        if(is_plugin_active('woocommerce-tm-extra-product-options/tm-woo-extra-product-options.php') == false)
            return false;
        $epos = null;
        $order_currency = $order->get_currency();
        $mt_prefix = $order_currency;
        $_product  = $order->get_product_from_item( $item );
        $item_meta = wc_get_order_item_meta($item_id, '');

        $order_taxes = $order->get_taxes();

        $check_box_html = ( version_compare( get_option( 'woocommerce_db_version' ), '2.6', '>=' ) )?'':'<td class="check-column">&nbsp;</td>';

        $has_epo = is_array($item)
                && isset($item['item_meta']) 
                && isset($item['item_meta']['_tmcartepo_data']) 
                && isset($item['item_meta']['_tmcartepo_data'][0])
                && isset($item['item_meta']['_tm_epo']);
        if ($has_epo){
            $current_product_id=$item['product_id'];
            $original_product_id = floatval(TM_EPO_WPML()->get_original_id( $current_product_id,'product' ));
            if (TM_EPO_WPML()->get_lang()==TM_EPO_WPML()->get_default_lang() && $original_product_id!=$current_product_id){
                $current_product_id = $original_product_id;
            }
            $wpml_translation_by_id=TM_EPO_WPML()->get_wpml_translation_by_id( $current_product_id );
        }
        if ($has_epo){
            $epos = maybe_unserialize($item['item_meta']['_tmcartepo_data'][0]);

            if ($epos && is_array($epos) ){
                
                foreach ($epos as $key => & $epo) {
                    if ($epo && is_array($epo)){

                        $new_currency = false;
                        if (isset($epo['price_per_currency'])){
                            $_current_currency_prices = $epo['price_per_currency'];
                            if ($mt_prefix!=='' 
                                    && $_current_currency_prices!=='' 
                                    && is_array($_current_currency_prices) 
                                    && isset($_current_currency_prices[$mt_prefix])
                                    && $_current_currency_prices[$mt_prefix]!=''){

                                $new_currency = true;
                                $epo['price'] = $_current_currency_prices[$mt_prefix];
                                
                            }
                        }
                        if(!$new_currency){
                            $type="";
                            if (isset($epo['element']) && isset($epo['element']['_']) &&isset($epo['element']['_']['price_type'])){
                                $type=$epo['element']["_"]['price_type'];
                            }
                            $epo['price'] = apply_filters('wc_epo_get_current_currency_price',$epo['price'],$type);
                        }

                        if(!isset($epo['quantity'])){
                            $epo['quantity'] = 1;
                        }
                        if(isset($wpml_translation_by_id[$epo['section']])){
                            $epo['name'] = $wpml_translation_by_id[$epo['section']];
                        }
                        if ( !isset($epo['price_per_currency']) && taxonomy_exists( $epo['name'] ) ) {
                            $epo['name'] = wc_attribute_label( $epo['name'] );
                        }
                        if(isset($wpml_translation_by_id["options_".$epo['section']]) 
                            && is_array($wpml_translation_by_id["options_".$epo['section']]) 
                            && !empty($epo['multiple']) 
                            && !empty($epo['key'])){
                            
                            $pos = strrpos($epo['key'], '_');
                            
                            if($pos!==false) {
                                
                                $av=array_values( $wpml_translation_by_id["options_".$epo['section']] );
                                
                                if (isset($av[substr($epo['key'], $pos+1)])){
                                    
                                    $epo['value'] = $av[substr($epo['key'], $pos+1)];
                                    
                                }

                            }

                        }
                        $display_value = $epo['value'];
                        if (is_array($epo['value'])){
                            $display_value = array_map('html_entity_decode', $display_value, version_compare(phpversion(), '5.4', '<') ? ENT_COMPAT : (ENT_COMPAT | ENT_HTML401) ,'UTF-8');
                        }else{
                            $display_value = html_entity_decode($display_value, version_compare(phpversion(), '5.4', '<') ? ENT_COMPAT : (ENT_COMPAT | ENT_HTML401) ,'UTF-8');
                        }
                        
                        if (!empty($epo['use_images']) && !empty($epo['images']) && $epo['use_images']=="images"){
                            $display_value ='<div class="cpf-img-on-cart"><img alt="" class="attachment-shop_thumbnail wp-post-image epo-option-image" src="'.apply_filters("tm_image_url",$epo['images']).'" /></div>'.esc_attr($display_value,'netbase-smart-invoice');
                        }

                        $display_value = apply_filters('tm_translate',$display_value);

                        if (isset($epo['element']) && isset($epo['element']['type']) && $epo['element']['type'] == 'upload'){
                            $check = wp_check_filetype( $epo['value'] );
                            if ( !empty( $check['ext'] ) ) {
                                $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
                                if ( in_array( $check['ext'], $image_exts ) ){
                                    $display_value ='<a target="_blank" href="'.$display_value.'"><span class="cpf-img-on-cart"><img alt="" class="attachment-shop_thumbnail wp-post-image epo-option-image epo-upload-image" src="'.
                                        apply_filters("tm_image_url",$epo['value']).'" /></span></a>';
                                }
                            }
                        }

                        if (!empty($epo['multiple_values'])){
                            $display_value_array=explode($epo['multiple_values'],$display_value);
                            $display_value="";
                            foreach ($display_value_array as $d => $dv) {
                                $display_value .='<span class="cpf-data-on-cart">'.$dv.'</span>';
                            }
                        }                       

                        $epo_name = apply_filters('tm_translate',$epo['name']);
                        $epo_value = make_clickable( $display_value );
                        $epo_quantity = ( $epo['quantity'] * (float) $item['item_meta']['_qty'][0] ).' <small>('.$epo['quantity'].'&times;'.(float) $item['item_meta']['_qty'][0].')</small>';
                        $epo_edit_value = true;
                        $edit_buttons = true;
                        $epo_edit_cost = true;
                        $epo_edit_quantity = true;
                        
                    }
                }

            }
        }
        return $epos;
    }

    function nb_invoice_create_file_tmp () {
        $upload_dir = wp_upload_dir();
        $upload_base = trailingslashit( $upload_dir['basedir'] );
        $base_path = trailingslashit($upload_base . 'nb_file_invoice_tmp/' );
        if (@is_dir( $base_path ) ) {
            return $base_path;
        }

        @mkdir( $base_path );

        $subfolders = array();
        foreach ( $subfolders as $subfolder ) {
            $path = $base_path . $subfolder . '/';
            @mkdir( $path );
            @file_put_contents( $path . '.htaccess', 'deny from all' );
            @touch( $path . 'index.php' );
        }

        @file_put_contents( $base_path . '.htaccess', 'deny from all' );
        @touch( $base_path . 'index.php' );
	}
	function invoice_getInvoiceOrder($order_id) {
        global $wpdb;
        $sql = "SELECT * FROM {$wpdb->prefix}netbase_invoice_order WHERE id_order=".absint($order_id);
        $item = $wpdb->get_row($sql, ARRAY_A);
        return $item;
    }
    function invoice_getMaxInvoiceNumber() {
        global $wpdb;
        $sql = "SELECT MAX(invoice_number) FROM {$wpdb->prefix}netbase_invoice_order ";
        return (int) $wpdb->get_var($sql);
    }
    function invoice_getMaxDeliveryNumber() {
        global $wpdb;
        $sql = "SELECT MAX(delivery_number) FROM {$wpdb->prefix}netbase_invoice_order ";
        return (int) $wpdb->get_var($sql);
    }

    function invoice_formatInvoiceNumber($invoice_info){
        
        $format = $this->template_setting_option['invoice_number_format'];
        $invoice_digits = $this->template_setting_option['digits'];
        $number = $invoice_info['invoice_number'];
        $number_formated = sprintf("%0{$invoice_digits}d",$number);
        $date_arr = date_parse($invoice_info['invoice_date']);
        $month = sprintf("%02d", $date_arr['month']);
        $day = sprintf("%02d", $date_arr['day']);
        $year = $date_arr['year'];
        $format = str_replace('[number]', $number_formated, $format);
        $format = str_replace('[m]', $month, $format);
        $format = str_replace('[Y]', $year, $format);
        $format = str_replace('[d]', $day, $format);
        return $format;
    }
    function invoice_formatDeliveryNumber($invoice_info){
        $format = $this->template_setting_option['delivery_number_format'];
        $invoice_digits = $this->template_setting_option['digits'];
        $number = $invoice_info['delivery_number'];
        $number_formated = sprintf("%0{$invoice_digits}d",$number);
        $date_arr = date_parse($invoice_info['delivery_date']);
        $month = sprintf("%02d", $date_arr['month']);
        $day = sprintf("%02d", $date_arr['day']);
        $year = $date_arr['year'];
        $format = str_replace('[number]', $number_formated, $format);
        $format = str_replace('[m]', $month, $format);
        $format = str_replace('[Y]', $year, $format);
        $format = str_replace('[d]', $day, $format);
        return $format;
    }
}