/includes/class-wcqc-export.php

  1. <?php 
  2. /** 
  3. * XML Export class 
  4. */ 
  5. if ( ! class_exists( 'WooCommerce_Qinvoice_Connect_Export' ) ) { 
  6.  
  7. class WooCommerce_Qinvoice_Connect_Export { 
  8.  
  9. public $order; 
  10. public $request_type; 
  11. public $order_id; 
  12.  
  13. /** 
  14. * Constructor 
  15. */ 
  16. public function __construct() {  
  17. global $woocommerce; 
  18. //$this->order = new WC_Order(); 
  19. $this->general_settings = get_option('wcqc_general_settings'); 
  20. add_action( 'wp_ajax_generate_wcqc', array($this, 'process_request_ajax' )); 
  21.  
  22.  
  23. /** 
  24. * Sends the actual request to the Q-invoice.com API 
  25. */ 
  26. public function send_request( $request_type = 'invoice', $order_id, $output = true ) { 
  27.  
  28.  
  29.  
  30. if ( !class_exists('qinvoice') ) { 
  31. require_once( WooCommerce_Qinvoice_Connect::$plugin_path . "includes/qinvoice.class.php" ); 
  32.  
  33. try{ 
  34.  
  35. $this->order = new WC_Order( $order_id ); 
  36. $document = new qinvoice($this->general_settings['api_username'] , $this->general_settings['api_password'], $this->general_settings['api_url']); 
  37. $document->identifier = 'wcqc_'. WooCommerce_Qinvoice_Connect::$version; 
  38. $document->setDocumentType($request_type); 
  39.  
  40. // customer note 
  41. $page_data = get_page( $order_id ); 
  42. $excerpt = strip_tags($page_data->post_excerpt); 
  43.  
  44.  
  45.  
  46.  
  47. $document->companyname = $this->order->billing_company; // Your customers company name 
  48.  
  49. $document->firstname = $this->order->billing_first_name; 
  50. $document->lastname = $this->order->billing_last_name; 
  51. $document->email = $this->order->billing_email; // Your customers emailaddress (invoice will be sent here) 
  52. $document->phone = $this->order->billing_phone; 
  53. $document->address = $this->order->billing_address_1; // Self-explanatory 
  54. $document->address2 = $this->order->billing_address_2; // Self-explanatory 
  55. $document->zipcode = $this->order->billing_postcode; // Self-explanatory 
  56. $document->city = $this->order->billing_city; // Self-explanatory 
  57. $document->country = $this->order->billing_country; // 2 character country code: NL for Netherlands, DE for Germany etc 
  58.  
  59. $document->vatnumber = get_post_meta( $order_id, 'VAT Number', true ); 
  60.  
  61. $document->delivery_firstname = $this->order->shipping_first_name; 
  62. $document->delivery_lastname = $this->order->shipping_last_name;  
  63. $document->delivery_address = $this->order->shipping_address_1;  
  64. $document->delivery_address = $this->order->shipping_address_1; // Self-explanatory 
  65. $document->delivery_address2 = $this->order->shipping_address_2; // Self-explanatory 
  66. $document->delivery_zipcode = $this->order->shipping_postcode; // Self-explanatory 
  67. $document->delivery_city = $this->order->shipping_city; // Self-explanatory 
  68. $document->delivery_country = $this->order->shipping_country; // 2 character country code: NL for Netherlands, DE for Germany etc 
  69. $document->delivery_phone = $this->order->billing_phone; 
  70.  
  71.  
  72. //https://www.tychesoftwares.com/store/premium-plugins/order-delivery-date-for-woocommerce-lite/ 
  73. if( get_post_meta($order_id, '_orddd_lite_timestamp', true) ) { 
  74. $document->delivery_date = Date('Y-m-d', get_post_meta($order_id, '_orddd_lite_timestamp', true) ); 
  75.  
  76. // not sure what the field name in pro version is. 'pro'? 
  77. if( get_post_meta($order_id, '_orddd_pro_timestamp', true) ) { 
  78. $document->delivery_date = Date('Y-m-d', get_post_meta($order_id, '_orddd_pro_timestamp', true) ); 
  79. // or just plain?  
  80. if( get_post_meta($order_id, '_orddd_timestamp', true) ) { 
  81. $document->delivery_date = Date('Y-m-d', get_post_meta($order_id, '_orddd_timestamp', true) ); 
  82.  
  83. $document->action = (int)$this->general_settings['invoice_action']; 
  84. $document->saverelation = (int)$this->general_settings['save_relation']; 
  85.  
  86. if(defined('WCML_VERSION') && 1==1) { 
  87. $currency = get_post_meta($order_id, '_order_currency', true); 
  88. $document->layout = (int)$this->general_settings['layout_code_'.$currency]; 
  89. $document->currency = $currency; 
  90. }else{ 
  91. $document->layout = (int)$this->general_settings['layout_code']; 
  92. $document->currency = get_woocommerce_currency(); 
  93.  
  94.  
  95.  
  96. $document->calculation_method = $this->general_settings['calculation_method']; 
  97.  
  98. $document->vat = ''; // Self-explanatory 
  99.  
  100. $order_date = explode(" ", $this->order->order_date); 
  101.  
  102. $date_format = get_option( 'date_format' ); 
  103.  
  104. $date = new DateTime($order_date[0]); 
  105.  
  106.  
  107. $remark = $this->general_settings['invoice_remark']; 
  108. $remark = str_replace('{order_id}', $order_id, $remark); 
  109. $remark = str_replace('{order_number}', $this->order->get_order_number(), $remark); 
  110. $remark = str_replace('{order_date}', $date->format($date_format), $remark); 
  111. $remark = str_replace('{customer_note}', $excerpt, $remark); 
  112. $paid_date = get_post_meta($order_id, '_paid_date', true); 
  113.  
  114. $paid = 0; 
  115. if($paid_date > 0000-00-00) { 
  116. // set paid or not 
  117. $paid = 1; 
  118. if($paid && $this->general_settings['send_payment_status'] != "no") { 
  119. $method = get_post_meta($order_id, '_payment_method_title', true); 
  120. $paidremark = $this->general_settings['paid_remark']; 
  121. $remark .= ' '. str_replace('{method}', $method, $paidremark); 
  122. }else{ 
  123. // reset value 
  124. $paid = 0; 
  125.  
  126. $document->payment_method = get_post_meta($order_id, '_payment_method_title', true); 
  127. $document->paid = $paid; 
  128. $document->remark = $remark; 
  129.  
  130. if($this->general_settings['invoice_date'] == 'order') { 
  131. $document->date = $order_date[0]; 
  132. }else{ 
  133. $document->date = Date('Y-m-d'); 
  134.  
  135. // OPTIONAL: Add tags 
  136. $document->addTag($order_id); 
  137. if(strlen($this->general_settings['invoice_tag']) > 0) { 
  138. $tag = $this->general_settings['invoice_tag']; 
  139. $tag = str_replace('{method}', $method, $tag); 
  140. $tag = str_replace('{order_number}', $this->order->get_order_number(), $tag); 
  141. $tag = str_replace('{order_date}', $date->format($date_format), $tag); 
  142. $document->addTag($tag); 
  143.  
  144. if(strlen($this->general_settings['invoice_reference']) > 0) { 
  145. $reference = $this->general_settings['invoice_reference']; 
  146. $reference = str_replace('{order_number}', $this->order->get_order_number(), $reference); 
  147. $document->document_reference = $reference; 
  148.  
  149. $default_ledger = $this->general_settings['default_ledger_account']; 
  150. $products_total = 0; 
  151.  
  152. foreach($this->get_order_items() as $item) { // Repeat this block for each product 
  153.  
  154. $_product = $item['item']; 
  155.  
  156. $sku = ''; 
  157.  
  158. $product = new WC_Product($_product['product_id']); 
  159.  
  160. $sku = $product->get_sku(); 
  161.  
  162. if($sku == '') { 
  163. $sku = $item['sku']; 
  164.  
  165.  
  166. if($item['quantity'] == 0 || $item['quantity'] == '') { 
  167. // skip  
  168. continue; 
  169. //echo '<hr/>'. $item['categories'] .'<hr/>'; 
  170. if($item['price_excl'] == 0 || $item['price_excl'] == '') { 
  171. $vatp = 0; 
  172. }else{ 
  173. $vatp = ($item['line_tax']/$item['quantity']) / $item['price_excl']; 
  174.  
  175. $vatp = $vatp * 10000; 
  176. $vatp = $item['tax_rate']*100; 
  177. if($this->order->order_tax == 0) { 
  178. // overwrite tax 
  179. $vatp = 0; 
  180.  
  181. // populate array with attributes 
  182. $attr_array = array(); 
  183. foreach(get_post_meta( $product->id , '_product_attributes' ) as $attr) { 
  184. foreach($attr as $name=>$attr_data) { 
  185. if($attr_data['is_variation'] == 1 || 1==1) { 
  186. $attr_array[] = $name; 
  187. $attr_names[$name] = $attr_data['name']; 
  188.  
  189.  
  190.  
  191. $item_desc = ''; 
  192.  
  193.  
  194. foreach($item['item']['item_meta'] as $key=>$val) { 
  195. $result_array = false; 
  196. if(in_array($key, $attr_array)) { 
  197.  
  198. $result = $val[0]; 
  199. $key = str_replace("attribute_pa_", "", $key); 
  200. $key = str_replace("attribute_", "", $key); 
  201. $key = str_replace("pa_", "", $key); 
  202. $item_desc .= "\n"; 
  203. $item_desc .= strlen($attr_names[$key]) > 0 ? $attr_names[$key] : ucfirst($key); 
  204. $item_desc .= ': '. $result; 
  205. }else{ 
  206. // get meta items that don't start with an underscore and only add them if add_item_meta is set 
  207. if(substr($key, 0, 1) != "_" && $this->general_settings['add_item_meta'] == 1) { 
  208. $item_desc .= "\n"; 
  209. $item_desc .= ucfirst($key); 
  210. $item_desc .= ': '. $val[0]; 
  211.  
  212. if(count($this->order->get_used_coupons()) > 0 || $item_total = $item['line_subtotal'] == $item_total = $item['line_total']) { 
  213. // use line_subtotal (without discount, discount added seperately) 
  214. $item_total = $item['line_subtotal']; 
  215. $item_tax = $item['line_subtotal_tax']; 
  216. }else{ 
  217. // use line_total (including manually added discounts without coupon) 
  218. $item_total = $item['line_total']; 
  219. $item_tax = $item['line_tax']; 
  220.  
  221.  
  222. $price = ($item_total/$item['quantity'])*100; 
  223.  
  224. $params = array( 'code' => $sku,  
  225. 'description' => str_replace(" ", "", $item['name'] . $item_desc), // Item description 
  226. 'price' => $price, // Item price, multiplied by 100: EUR 10 becomes 1000 
  227. 'price_incl' => (($item_total + $item_tax)/$item['quantity'])*100,  
  228. 'price_vat' => round(($item_tax/$item['quantity'])*100),  
  229. 'vatpercentage' => $vatp, // Item vat percentage, multiplied by 100: 19% becomes 1900 (without '%') 
  230. 'discount' => 0, // Discount percentage, also multiplied by 100 without '%' 
  231. 'quantity' => $item['quantity']*100, // Item quantity, again multiplied by 100 (1.75 becomes 175, 1 becomes 100) 
  232. 'categories' => $item['categories'], // Categories 
  233. 'ledgeraccount' => ($item['ledgeraccount'] > 0) ? $item['ledgeraccount'] : $default_ledger // Ledger account 
  234. ); 
  235.  
  236.  
  237.  
  238. $document->addItem($params); 
  239. $products_total += $price; 
  240.  
  241.  
  242. if(method_exists($this->order, 'get_total_shipping')) { 
  243. $total_shipping = $this->order->get_total_shipping(); 
  244. }else{ 
  245. $total_shipping = $this->order->get_shipping(); 
  246.  
  247. if($total_shipping > 0) { 
  248. $vatp = $this->order->get_shipping_tax() / $total_shipping; 
  249. $vatp = round($vatp*100) * 100; 
  250. $params = array( 'code' => 'SHPMNT',  
  251. 'description' => $this->order->get_shipping_method(), // Item description 
  252. 'price_incl' => ($total_shipping + $this->order->get_shipping_tax())*100, // Item price, multiplied by 100: EUR 10 becomes 1000 
  253. 'price' => $total_shipping*100,  
  254. 'price_vat' => $this->order->get_shipping_tax()*100,  
  255. 'vatpercentage' => round($vatp), // Item vat percentage, multiplied by 100: 19% becomes 1900 (without '%') 
  256. 'discount' => 0, // Discount percentage, also multiplied by 100 without '%' 
  257. 'quantity' => 100, // Item quantity, again multiplied by 100 (1.75 becomes 175, 1 becomes 100) 
  258. 'categories' => 'shipping' // Categories 
  259. ); 
  260.  
  261. $document->addItem($params); 
  262.  
  263.  
  264.  
  265.  
  266. /** 
  267. * Return the order fees 
  268. */ 
  269. if(method_exists($this->order, 'get_fees')) { 
  270. if ( $fees = $this->order->get_fees() ) { 
  271. foreach( $fees as $id => $fee ) { 
  272. $tax = new WC_Tax(); 
  273. $rates = ($tax->get_rates($fee['tax_class'])); 
  274.  
  275. foreach($rates as $rate) { 
  276. $tax_rate = $rate['rate']; 
  277.  
  278. $price = ($fee['line_total']*100 / (100+$tax_rate))*100; 
  279. $price_incl = ($fee['line_total'])*100; 
  280. $price_vat = $price_incl - $price; 
  281.  
  282. $params = array(  
  283. 'code' => 'CSTS',  
  284. 'description' => $fee['name'],  
  285. 'price' => $price,  
  286. 'price_incl' => $price_incl,  
  287. 'price_vat' => $price_vat,  
  288. 'vatpercentage' => $tax_rate*100,  
  289. 'discount' => 0,  
  290. 'quantity' => 100,  
  291. 'categories' => 'fees' 
  292. ); 
  293. $document->addItem($params); 
  294. }catch (Exception $e) { 
  295. echo 'Caught exception: ', $e->getMessage(), "\n"; 
  296.  
  297.  
  298.  
  299. $discount = false; 
  300. $description = ''; 
  301. foreach($this->order->get_used_coupons() as $code) { 
  302. $coupon = new WC_Coupon($code); 
  303.  
  304. //echo $this->general_settings['coupon_vat']; 
  305. if($coupon->apply_before_tax == 'no') { 
  306. $vatp = 0; 
  307. }else{ 
  308. $vatp = get_option( WooCommerce_Qinvoice_Connect::$plugin_prefix . 'coupon_vat' ); 
  309. if($vatp == '') { 
  310. // fallback 
  311. $vatp = $this->general_settings['coupon_vat']; 
  312. $discount = true; 
  313. $description .= $code .' '; 
  314.  
  315. // calculate price for discount 
  316. $price = $this->order->get_total_discount(); 
  317. $price_incl = round($this->order->get_total_discount()*(100 + $vatp), 2)/100; 
  318. $price_vat = $price_incl - $price; 
  319.  
  320.  
  321.  
  322. if($discount == true) { 
  323. $params = array(  
  324. 'code' => 'DSCNT',  
  325. 'description' => $description,  
  326. 'price' => $price*-100,  
  327. 'price_incl' => $price_incl*-100,  
  328. 'price_vat' => $price_vat*-100,  
  329. 'vatpercentage' => $vatp*100,  
  330. 'discount' => 0,  
  331. 'quantity' => 100,  
  332. 'categories' => 'discount' 
  333. ); 
  334. $document->addItem($params); 
  335.  
  336. return $result = $document->sendRequest(); 
  337.  
  338. unset($this->order); 
  339.  
  340. /** 
  341. * Send request for each order_id 
  342. */ 
  343. public function process_request( $request_type = 'invoice', $order_ids, $output = false ) { 
  344. $html = ''; 
  345. foreach ($order_ids as $order_id) { 
  346. $result = $this->send_request( $request_type, $order_id ); 
  347. // sleep(1); 
  348. $request_type = explode(".", $request_type); 
  349. $request_type = $request_type[0]; 
  350. $html .= 'Order '. $order_id .': '; 
  351. if($result == true) { 
  352. //add_post_meta($order_id, '_invoiced', true, true);  
  353. if($request_type == 'invoice') { 
  354. $html .= __('Invoice generated.', 'wcqc'); 
  355. }elseif($request_type == 'quote') { 
  356. $html .= __('Quote generated.', 'wcqc'); 
  357. }elseif($request_type == 'orderconfirmation') { 
  358. $html .= __('Order confirmation generated.', 'wcqc'); 
  359. }elseif($request_type == 'recurring') { 
  360. $html .= __('Recurring invoice generated.', 'wcqc'); 
  361. }elseif($request_type == 'proforma') { 
  362. $html .= __('Proforma invoice generated.', 'wcqc'); 
  363. }else{ 
  364. $html .= __('Uhoh. Something went wrong.', 'wcqc'); 
  365. $html .= '<br />'; 
  366. if($output == true) { 
  367. echo $html;  
  368.  
  369. /** 
  370. * Load and generate the template output with ajax 
  371. */ 
  372. public function process_request_ajax() { 
  373. // Check the nonce 
  374. if( !is_user_logged_in() || !check_admin_referer( $_GET['action'] ) ) { 
  375. wp_die( __( 'You do not have sufficient permissions to access this page.', 'wcqc' ) ); 
  376.  
  377. // Check if all parameters are set 
  378. if( empty( $_GET['request_type'] ) || empty( $_GET['order_ids'] ) ) { 
  379. wp_die( __( 'Missing parameters.', 'wcqc' ) ); 
  380.  
  381. // Check the user privileges 
  382. if( !current_user_can( 'manage_woocommerce_orders' ) && !current_user_can( 'edit_shop_orders' ) ) { 
  383. wp_die( __( 'You do not have sufficient permissions to access this page.', 'wcqc' ) ); 
  384.  
  385. $order_ids = (array) explode('x', $_GET['order_ids']); 
  386. // Process oldest first: reverse $order_ids array 
  387. $order_ids = array_reverse($order_ids); 
  388.  
  389. // Generate the output 
  390. $request_type = $_GET['request_type']; 
  391. // die($this->process_template( $request_type, $order_ids )); // or use the filter switch below! 
  392.  
  393. $document = $this->process_request( $request_type, $order_ids, true ); 
  394.  
  395.  
  396. echo '<hr /> <a href="javascript:window.close();">'. __('close this window.', 'wcqc') .'</a>'; 
  397.  
  398.  
  399. exit; 
  400.  
  401.  
  402. /** 
  403. * Get the current order 
  404. */ 
  405. public function get_order() { 
  406. return $this->order; 
  407.  
  408. /** 
  409. * Get the current order items 
  410. */ 
  411. public function get_order_items_v2() { 
  412. global $woocommerce; 
  413. global $_product; 
  414.  
  415. $items = $this->order->get_items(); 
  416. $data_list = array(); 
  417.  
  418. if( sizeof( $items ) > 0 ) { 
  419. foreach ( $items as $item ) { 
  420. // Array with data for the pdf template 
  421. $data = array(); 
  422.  
  423. // Set the id 
  424. $data['product_id'] = $item['product_id']; 
  425. $data['variation_id'] = $item['variation_id']; 
  426.  
  427. // Set item name 
  428. $data['name'] = $item['name']; 
  429.  
  430. // Set item quantity 
  431. $data['quantity'] = $item['qty']; 
  432.  
  433. // Set the line total (=after discount) 
  434. $quantity_divider = ( $item['qty'] == 0 ) ? 1 : $item['qty']; // prevent division by zero 
  435. $data['line_total'] = $item['line_total'] ; 
  436. $data['single_line_total'] = $item['line_total'] / $quantity_divider ; 
  437. $data['line_tax'] = $item['line_tax'] ; 
  438. $data['single_line_tax'] = $item['line_tax'] / $quantity_divider ; 
  439. $data['tax_rate'] = $this->get_tax_rate( $item['tax_class'], $item['line_total'], $item['line_tax'] ); 
  440.  
  441. // Set the line subtotal (=before discount) 
  442. $data['line_subtotal'] = $item['line_subtotal'] ; 
  443. $data['line_subtotal_tax'] = $item['line_subtotal_tax'] ; 
  444. $data['ex_price'] = $item ; 
  445. $data['price'] = $item ; 
  446. $data['order_price'] = $this->order->get_formatted_line_subtotal( $item ); // formatted according to WC settings 
  447.  
  448. // Calculate the single price with the same rules as the formatted line subtotal (!) 
  449. // = before discount 
  450. $data['ex_single_price'] = $this->get_formatted_item_price ( $item, 'single', 'excl' ); 
  451. $data['single_price'] = $this->get_formatted_item_price ( $item, 'single' ); 
  452.  
  453. // Set item meta and replace it when it is empty 
  454. $meta = new WC_Order_Item_Meta( $item['item_meta'] );  
  455. $data['meta'] = $meta->display( false, true ); 
  456.  
  457. $WC_Tax = new WC_Tax(); 
  458.  
  459. // Pass complete item array 
  460. $data['item'] = $item; 
  461.  
  462. // Create the product to display more info 
  463. $data['product'] = null; 
  464.  
  465. $product = $this->order->get_product_from_item( $item ); 
  466.  
  467. // Checking fo existance, thanks to MDesigner0  
  468. if(!empty($product)) { 
  469.  
  470. // Set item SKU 
  471. $data['sku'] = $product->get_sku(); 
  472.  
  473. // Set item weight 
  474. $data['weight'] = $product->get_weight(); 
  475.  
  476. // Set item dimensions 
  477. $data['dimensions'] = $product->get_dimensions(); 
  478.  
  479. // Pass complete product object 
  480. $data['product'] = $product; 
  481.  
  482. $data['categories'] = ''; 
  483.  
  484. $data['price_excl'] = $product->get_price_excluding_tax(1); 
  485.  
  486. //$data['tax_class'] = $product->get_tax_status(); 
  487.  
  488. $data['categories'] = get_post_meta($product->id, 'categories', true ); 
  489. //echo '<hr />'. $product->get_tax_class(); 
  490.  
  491.  
  492.  
  493. $data_list[] = apply_filters( 'wcqc_order_item_data', $data ); 
  494.  
  495. return apply_filters( 'wcqc_order_items_data', $data_list ); 
  496.  
  497. public function get_order_items() { 
  498. global $woocommerce; 
  499. global $_product; 
  500.  
  501. $items = $this->order->get_items(); 
  502. $tax = $this->order->get_items( 'tax' ); 
  503. $data_list = array(); 
  504.  
  505. if( sizeof( $items ) > 0 ) { 
  506. //print_r($items); 
  507. //print_r($tax); 
  508. foreach ( $items as $item ) { 
  509. // Array with data for the printing template 
  510. $data = array(); 
  511.  
  512.  
  513.  
  514. // Set the id 
  515. $data['product_id'] = $item['product_id']; 
  516. $data['variation_id'] = $item['variation_id']; 
  517.  
  518. // Set item name 
  519. $data['name'] = $item['name']; 
  520.  
  521. // Set item quantity 
  522. $data['quantity'] = $item['qty']; 
  523.  
  524. // Set the subtotal for the number of products 
  525. $data['line_total'] = $item['line_total']; 
  526. $data['line_tax'] = $item['line_tax']; 
  527.  
  528. // Set the final subtotal for all products 
  529. $data['line_subtotal'] = $item['line_subtotal']; 
  530. $data['line_subtotal_tax'] = $item['line_subtotal_tax']; 
  531. $data['formatted_line_subtotal'] = $this->order->get_formatted_line_subtotal( $item ); 
  532. $data['price'] = $data['formatted_line_subtotal']; 
  533.  
  534. // Set item meta and replace it when it is empty 
  535. $meta = new WC_Order_Item_Meta( $item['item_meta'] );  
  536. $data['meta'] = $meta->display( false, true ); 
  537. $WC_Tax = new WC_Tax(); 
  538.  
  539.  
  540. // Pass complete item array 
  541. $data['item'] = $item; 
  542.  
  543. // Create the product to display more info 
  544. $data['product'] = null; 
  545.  
  546. $product = $this->order->get_product_from_item( $item ); 
  547.  
  548. // Checking fo existance, thanks to MDesigner0  
  549. if(!empty($product)) {  
  550. //print_r($product); 
  551. // Set the single price 
  552. $data['single_price'] = $product->get_price(); 
  553.  
  554. // Set item SKU 
  555. $data['sku'] = $product->get_sku(); 
  556.  
  557. // Set item weight 
  558. $data['weight'] = $product->get_weight(); 
  559.  
  560.  
  561. // Set item dimensions 
  562. $data['dimensions'] = $product->get_dimensions(); 
  563.  
  564. // Pass complete product object 
  565. $data['product'] = $product; 
  566.  
  567. $data['categories'] = ''; 
  568.  
  569. $data['price_excl'] = $product->get_price_excluding_tax(1); 
  570.  
  571. //$data['tax_class'] = $product->get_tax_status(); 
  572.  
  573. $data['categories'] = get_post_meta($product->id, 'categories', true ); 
  574. //echo '<hr />'. $product->get_tax_class(); 
  575. $rates = ($WC_Tax->get_rates($product->get_tax_class())); 
  576. //print_r($rates); 
  577. foreach($rates as $r) { 
  578. $data['tax_rate'] = $r['rate']; 
  579.  
  580. //print_r($data); 
  581.  
  582.  
  583. $data_list[] = $data; 
  584.  
  585. return $data_list ; 
  586.  
  587. /** 
  588. * Get the tax rates/percentages for a given tax class 
  589. * @param string $tax_class tax class slug 
  590. * @return string $tax_rates imploded list of tax rates 
  591. */ 
  592. public function get_tax_rate( $tax_class, $line_total, $line_tax ) { 
  593. if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) { 
  594. // WC 2.1 or newer is used 
  595. if ( $line_tax == 0 ) { 
  596. return '-'; // no need to determine tax rate... 
  597.  
  598. // if (empty($tax_class)) 
  599. // $tax_class = 'standard';// does not appear to work anymore - get_rates does accept an empty tax_class though! 
  600.  
  601. $tax = new WC_Tax(); 
  602. $taxes = $tax->get_rates( $tax_class ); 
  603.  
  604. $tax_rates = array(); 
  605.  
  606. foreach ($taxes as $tax) { 
  607. $tax_rates[$tax['label']] = round( $tax['rate'], 2 ); 
  608.  
  609. if (empty($tax_rates)) { 
  610. // one last try: manually calculate 
  611. if ( $line_total != 0) { 
  612. $tax_rates[] = round( ($line_tax / $line_total)*100, 1 ); 
  613. } else { 
  614. $tax_rates[] = '-'; 
  615.  
  616. $tax_rates = implode(' , ', $tax_rates ); 
  617. } else { 
  618. // Backwards compatibility: calculate tax from line items 
  619. if ( $line_total != 0) { 
  620. $tax_rates = round( ($line_tax / $line_total)*100, 1 ); 
  621. } else { 
  622. $tax_rates = '-'; 
  623.  
  624. return $tax_rates; 
  625.  
  626. /** 
  627. * wrapper for wc2.1 depricated price function 
  628. */ 
  629. public function wc_price( $price, $args = array() ) { 
  630. if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) { 
  631. // WC 2.1 or newer is used 
  632. $args['currency'] = $this->order->get_order_currency(); 
  633. $formatted_price = wc_price( $price, $args ); 
  634. } else { 
  635. $formatted_price = woocommerce_price( $price ); 
  636.  
  637. return $formatted_price; 
  638.  
  639. /** 
  640. * Gets price - formatted for display. 
  641. * 
  642. * @access public 
  643. * @param mixed $item 
  644. * @return string 
  645. */ 
  646. public function get_formatted_item_price ( $item, $type, $tax_display = '' ) { 
  647. $item_price = 0; 
  648. $divider = ($type == 'single' && $item['qty'] != 0 )?$item['qty']:1; //divide by 1 if $type is not 'single' (thus 'total') 
  649.  
  650. if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) )  
  651. return; 
  652.  
  653. if ( $tax_display == 'excl' ) { 
  654. $item_price = $this->wc_price( ($this->order->get_line_subtotal( $item )) / $divider ); 
  655. } else { 
  656. $item_price = $this->wc_price( ($this->order->get_line_subtotal( $item, true )) / $divider ); 
  657.  
  658. return $item_price; 
  659.  
  660. /** 
  661. * Get order custom field 
  662. */ 
  663. public function get_order_field( $field ) { 
  664. if( isset( $this->get_order()->order_custom_fields[$field] ) ) { 
  665. return $this->get_order()->order_custom_fields[$field][0]; 
  666. }  
  667. return; 
  668.  
  669.  
  670.  
  671.  
.