WooCommerce_PDF_Invoices_Functions

The WooCommerce PDF Invoices & Packing Slips WooCommerce PDF Invoices Functions class.

Defined (2)

The class is defined in the following location(s).

/includes/class-wcpdf-functions.php  
  1. class WooCommerce_PDF_Invoices_Functions { 
  2.  
  3. /** 
  4. * Get template name from slug 
  5. */ 
  6. public function get_template_name ( $template_type ) { 
  7. switch ( $template_type ) { 
  8. case 'invoice': 
  9. $template_name = apply_filters( 'wpo_wcpdf_invoice_title', __( 'Invoice', 'wpo_wcpdf' ) ); 
  10. break; 
  11. case 'packing-slip': 
  12. $template_name = apply_filters( 'wpo_wcpdf_packing_slip_title', __( 'Packing Slip', 'wpo_wcpdf' ) ); 
  13. break; 
  14. default: 
  15. // try to 'unslug' the name 
  16. $template_name = ucwords( str_replace( array( '_', '-' ), ' ', $template_type ) ); 
  17. break; 
  18.  
  19. return apply_filters( 'wpo_wcpdf_template_name', $template_name, $template_type ); 
  20.  
  21. /** 
  22. * Output template styles 
  23. */ 
  24. public function template_styles() { 
  25. $css = apply_filters( 'wpo_wcpdf_template_styles_file', WPO_WCPDF()->export->template_path. '/' .'style.css' ); 
  26.  
  27. ob_start(); 
  28. if (file_exists($css)) { 
  29. include($css); 
  30. $html = ob_get_clean(); 
  31. $html = apply_filters( 'wpo_wcpdf_template_styles', $html ); 
  32.  
  33. echo $html; 
  34.  
  35. /** 
  36. * Return logo id 
  37. */ 
  38. public function get_header_logo_id() { 
  39. if (isset(WPO_WCPDF()->settings->template_settings['header_logo'])) { 
  40. return apply_filters( 'wpo_wcpdf_header_logo_id', WPO_WCPDF()->settings->template_settings['header_logo'] ); 
  41.  
  42. /** 
  43. * Show logo html 
  44. */ 
  45. public function header_logo() { 
  46. if ($this->get_header_logo_id()) { 
  47. $attachment_id = $this->get_header_logo_id(); 
  48. $company = isset(WPO_WCPDF()->settings->template_settings['shop_name'])? WPO_WCPDF()->settings->template_settings['shop_name'] : ''; 
  49. if( $attachment_id ) { 
  50. $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false ); 
  51.  
  52. $attachment_src = $attachment[0]; 
  53. $attachment_width = $attachment[1]; 
  54. $attachment_height = $attachment[2]; 
  55.  
  56. $attachment_path = get_attached_file( $attachment_id ); 
  57.  
  58. if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) { 
  59. $src = $attachment_path; 
  60. } else { 
  61. $src = $attachment_src; 
  62.  
  63. printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) ); 
  64.  
  65. /** 
  66. * Return/Show custom company name or default to blog name 
  67. */ 
  68. public function get_shop_name() { 
  69. if (!empty(WPO_WCPDF()->settings->template_settings['shop_name'])) { 
  70. $name = trim( WPO_WCPDF()->settings->template_settings['shop_name'] ); 
  71. return apply_filters( 'wpo_wcpdf_shop_name', wptexturize( $name ) ); 
  72. } else { 
  73. return apply_filters( 'wpo_wcpdf_shop_name', get_bloginfo( 'name' ) ); 
  74. public function shop_name() { 
  75. echo $this->get_shop_name(); 
  76.  
  77. /** 
  78. * Return/Show shop/company address if provided 
  79. */ 
  80. public function get_shop_address() { 
  81. $shop_address = apply_filters( 'wpo_wcpdf_shop_address', wpautop( wptexturize( WPO_WCPDF()->settings->template_settings['shop_address'] ) ) ); 
  82. if (!empty($shop_address)) { 
  83. return $shop_address; 
  84. } else { 
  85. return false; 
  86. public function shop_address() { 
  87. echo $this->get_shop_address(); 
  88.  
  89. /** 
  90. * Check if billing address and shipping address are equal 
  91. */ 
  92. public function ships_to_different_address() { 
  93. $order = &WPO_WCPDF()->export->order; 
  94. $order_id = WCX_Order::get_id( $order ); 
  95. // always prefer parent address for refunds 
  96. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  97. $current_order = $order; 
  98. $order = WCX::get_order( $parent_order_id ); 
  99.  
  100. $address_comparison_fields = apply_filters( 'wpo_wcpdf_address_comparison_fields', array( 
  101. 'first_name',  
  102. 'last_name',  
  103. 'company',  
  104. 'address_1',  
  105. 'address_2',  
  106. 'city',  
  107. 'state',  
  108. 'postcode',  
  109. 'country' 
  110. ) ); 
  111.  
  112. foreach ($address_comparison_fields as $address_field) { 
  113. $billing_field = WCX_Order::get_prop( $order, "billing_{$address_field}", 'view'); 
  114. $shipping_field = WCX_Order::get_prop( $order, "shipping_{$address_field}", 'view'); 
  115. if ( $shipping_field != $billing_field ) { 
  116. // this address field is different -> ships to different address! 
  117. $order = isset($current_order) ? $current_order : $order; // reset back to refund if necessery 
  118. return true; 
  119.  
  120. //if we got here, it means the addresses are equal -> doesn't ship to different address! 
  121. $order = isset($current_order) ? $current_order : $order; // reset back to refund if necessery 
  122. return apply_filters( 'wpo_wcpdf_ships_to_different_address', false, $order ); 
  123.  
  124. /** 
  125. * Return/Show billing address 
  126. */ 
  127. public function get_billing_address() { 
  128. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  129. // always prefer parent billing address for refunds 
  130. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  131. // temporarily switch order to make all filters / order calls work correctly 
  132. $current_order = WPO_WCPDF()->export->order; 
  133. WPO_WCPDF()->export->order = WCX::get_order( $parent_order_id ); 
  134. $address = apply_filters( 'wpo_wcpdf_billing_address', WPO_WCPDF()->export->order->get_formatted_billing_address() ); 
  135. // switch back & unset 
  136. WPO_WCPDF()->export->order = $current_order; 
  137. unset($current_order); 
  138. } elseif ( $address = WPO_WCPDF()->export->order->get_formatted_billing_address() ) { 
  139. // regular shop_order 
  140. $address = apply_filters( 'wpo_wcpdf_billing_address', $address ); 
  141. } else { 
  142. // no address 
  143. $address = apply_filters( 'wpo_wcpdf_billing_address', __('N/A', 'wpo_wcpdf') ); 
  144.  
  145. return $address; 
  146. public function billing_address() { 
  147. echo $this->get_billing_address(); 
  148.  
  149. /** 
  150. * Return/Show billing email 
  151. */ 
  152. public function get_billing_email() { 
  153. $billing_email = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'billing_email', 'view' ); 
  154.  
  155. if ( !$billing_email && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  156. // try parent 
  157. $parent_order = WCX::get_order( $parent_order_id ); 
  158. $billing_email = WCX_Order::get_prop( $parent_order, 'billing_email', 'view' ); 
  159.  
  160. return apply_filters( 'wpo_wcpdf_billing_email', $billing_email ); 
  161. public function billing_email() { 
  162. echo $this->get_billing_email(); 
  163.  
  164. /** 
  165. * Return/Show billing phone 
  166. */ 
  167. public function get_billing_phone() { 
  168. $billing_phone = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'billing_phone', 'view' ); 
  169.  
  170. if ( !$billing_phone && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  171. // try parent 
  172. $parent_order = WCX::get_order( $parent_order_id ); 
  173. $billing_phone = WCX_Order::get_prop( $parent_order, 'billing_phone', 'view' ); 
  174.  
  175. return apply_filters( 'wpo_wcpdf_billing_phone', $billing_phone ); 
  176. public function billing_phone() { 
  177. echo $this->get_billing_phone(); 
  178.  
  179. /** 
  180. * Return/Show shipping address 
  181. */ 
  182. public function get_shipping_address() { 
  183. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  184.  
  185. // always prefer parent shipping address for refunds 
  186. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  187. // temporarily switch order to make all filters / order calls work correctly 
  188. $current_order = WPO_WCPDF()->export->order; 
  189. WPO_WCPDF()->export->order = WCX::get_order( $parent_order_id ); 
  190. $address = apply_filters( 'wpo_wcpdf_shipping_address', WPO_WCPDF()->export->order->get_formatted_shipping_address() ); 
  191. // switch back & unset 
  192. WPO_WCPDF()->export->order = $current_order; 
  193. unset($current_order); 
  194. } elseif ( $address = WPO_WCPDF()->export->order->get_formatted_shipping_address() ) { 
  195. // regular shop_order 
  196. $address = apply_filters( 'wpo_wcpdf_shipping_address', $address ); 
  197. } else { 
  198. // no address 
  199. $address = apply_filters( 'wpo_wcpdf_shipping_address', __('N/A', 'wpo_wcpdf') ); 
  200.  
  201. return $address; 
  202. public function shipping_address() { 
  203. echo $this->get_shipping_address(); 
  204.  
  205. /** 
  206. * Return/Show a custom field 
  207. */  
  208. public function get_custom_field( $field_name ) { 
  209. $custom_field = WCX_Order::get_meta( WPO_WCPDF()->export->order, $field_name, true ); 
  210.  
  211. if ( !$custom_field && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  212. // try parent 
  213. $parent_order = WCX::get_order( $parent_order_id ); 
  214. $custom_field = WCX_Order::get_meta( $parent_order, $field_name, true ); 
  215.  
  216. return apply_filters( 'wpo_wcpdf_billing_custom_field', $custom_field ); 
  217. public function custom_field( $field_name, $field_label = '', $display_empty = false ) { 
  218. $custom_field = $this->get_custom_field( $field_name ); 
  219. if (!empty($field_label)) { 
  220. // add a a trailing space to the label 
  221. $field_label .= ' '; 
  222.  
  223. if (!empty($custom_field) || $display_empty) { 
  224. echo $field_label . nl2br ($custom_field); 
  225.  
  226. /** 
  227. * Return/Show order notes 
  228. */  
  229. public function get_order_notes( $filter = 'customer' ) { 
  230. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  231. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  232. $post_id = $parent_order_id; 
  233. } else { 
  234. $post_id = $order_id; 
  235.  
  236. $args = array( 
  237. 'post_id' => $post_id,  
  238. 'approve' => 'approve',  
  239. 'type' => 'order_note' 
  240. ); 
  241.  
  242. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  243.  
  244. $notes = get_comments( $args ); 
  245.  
  246. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  247.  
  248. if ( $notes ) { 
  249. foreach( $notes as $key => $note ) { 
  250. if ( $filter == 'customer' && !get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ) { 
  251. unset($notes[$key]); 
  252. if ( $filter == 'private' && get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ) { 
  253. unset($notes[$key]); 
  254. }  
  255. return $notes; 
  256. public function order_notes( $filter = 'customer' ) { 
  257. $notes = $this->get_order_notes( $filter ); 
  258. if ( $notes ) { 
  259. foreach( $notes as $note ) { 
  260. ?> 
  261. <div class="note_content"> 
  262. <?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?> 
  263. </div> 
  264. <?php 
  265.  
  266. /** 
  267. * Return/Show the current date 
  268. */ 
  269. public function get_current_date() { 
  270. return apply_filters( 'wpo_wcpdf_date', date_i18n( get_option( 'date_format' ) ) ); 
  271. public function current_date() { 
  272. echo $this->get_current_date(); 
  273.  
  274. /** 
  275. * Return/Show payment method  
  276. */ 
  277. public function get_payment_method() { 
  278. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  279. $payment_method_label = __( 'Payment method', 'wpo_wcpdf' ); 
  280.  
  281. // use parent for credit notes 
  282. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  283. $parent_order = WCX::get_order( $parent_order_id ); 
  284. $payment_method_title = WCX_Order::get_prop( $parent_order, 'payment_method_title', 'view' ); 
  285. $payment_method = __( $payment_method_title, 'woocommerce' ); 
  286. } else { 
  287. $payment_method_title = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'payment_method_title', 'view' ); 
  288.  
  289. $payment_method = __( $payment_method_title, 'woocommerce' ); 
  290.  
  291. return apply_filters( 'wpo_wcpdf_payment_method', $payment_method ); 
  292. public function payment_method() { 
  293. echo $this->get_payment_method(); 
  294.  
  295. /** 
  296. * Return/Show shipping method  
  297. */ 
  298. public function get_shipping_method() { 
  299. $shipping_method_label = __( 'Shipping method', 'wpo_wcpdf' ); 
  300. return apply_filters( 'wpo_wcpdf_shipping_method', __( WPO_WCPDF()->export->order->get_shipping_method(), 'woocommerce' ) ); 
  301. public function shipping_method() { 
  302. echo $this->get_shipping_method(); 
  303.  
  304. /** 
  305. * Return/Show order number 
  306. */ 
  307. public function get_order_number() { 
  308. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  309. // try parent first 
  310. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  311. $parent_order = WCX::get_order( $parent_order_id ); 
  312. $order_number = $parent_order->get_order_number(); 
  313. } else { 
  314. $order_number = WPO_WCPDF()->export->order->get_order_number(); 
  315.  
  316. // Trim the hash to have a clean number but still  
  317. // support any filters that were applied before. 
  318. $order_number = ltrim($order_number, '#'); 
  319. return apply_filters( 'wpo_wcpdf_order_number', $order_number); 
  320. public function order_number() { 
  321. echo $this->get_order_number(); 
  322.  
  323. /** 
  324. * Return/Show invoice number  
  325. */ 
  326. public function get_invoice_number() { 
  327. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  328. // try parent first 
  329. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  330. $invoice_number = WPO_WCPDF()->export->get_invoice_number( $parent_order_id ); 
  331. } else { 
  332. $invoice_number = WPO_WCPDF()->export->get_invoice_number( $order_id ); 
  333.  
  334. return $invoice_number; 
  335. public function invoice_number() { 
  336. echo $this->get_invoice_number(); 
  337.  
  338. /** 
  339. * Return/Show the order date 
  340. */ 
  341. public function get_order_date() { 
  342. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  343. // try parent first 
  344. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  345. $parent_order = WCX::get_order( $parent_order_id ); 
  346. $order_date = WCX_Order::get_prop( $parent_order, 'date_created' ); 
  347. } else { 
  348. $order_date = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'date_created' ); 
  349.  
  350. $date = $order_date->date_i18n( get_option( 'date_format' ) ); 
  351. $mysql_date = $order_date->date( "Y-m-d H:i:s" ); 
  352. return apply_filters( 'wpo_wcpdf_order_date', $date, $mysql_date ); 
  353. public function order_date() { 
  354. echo $this->get_order_date(); 
  355.  
  356. /** 
  357. * Return/Show the invoice date 
  358. */ 
  359. public function get_invoice_date() { 
  360. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  361. $invoice_date = WPO_WCPDF()->export->get_invoice_date( $order_id ); 
  362. return $invoice_date; 
  363. public function invoice_date() { 
  364. echo $this->get_invoice_date(); 
  365.  
  366. /** 
  367. * Return the order items 
  368. */ 
  369. public function get_order_items() { 
  370. return apply_filters( 'wpo_wcpdf_order_items', WPO_WCPDF()->export->get_order_items() ); 
  371.  
  372. /** 
  373. * Return/show product attribute 
  374. */ 
  375. public function get_product_attribute( $attribute_name, $product ) { 
  376. // first, check the text attributes 
  377. $attributes = $product->get_attributes(); 
  378. $attribute_key = @wc_attribute_taxonomy_name( $attribute_name ); 
  379. if (array_key_exists( sanitize_title( $attribute_name ), $attributes) ) { 
  380. $attribute = $product->get_attribute ( $attribute_name ); 
  381. return $attribute; 
  382. } elseif (array_key_exists( sanitize_title( $attribute_key ), $attributes) ) { 
  383. $attribute = $product->get_attribute ( $attribute_key ); 
  384. return $attribute; 
  385.  
  386. // not a text attribute, try attribute taxonomy 
  387. $attribute_key = @wc_attribute_taxonomy_name( $attribute_name ); 
  388. $product_id = WCX_Product::get_prop($product, 'id'); 
  389. $product_terms = @wc_get_product_terms( $product_id, $attribute_key, array( 'fields' => 'names' ) ); 
  390. // check if not empty, then display 
  391. if ( !empty($product_terms) ) { 
  392. $attribute = array_shift( $product_terms ); 
  393. return $attribute; 
  394. } else { 
  395. // no attribute under this name 
  396. return false; 
  397. public function product_attribute( $attribute_name, $product ) { 
  398. echo $this->get_product_attribute( $attribute_name, $product ); 
  399.  
  400.  
  401. /** 
  402. * Return the order totals listing 
  403. */ 
  404. public function get_woocommerce_totals() { 
  405. // get totals and remove the semicolon 
  406. $totals = apply_filters( 'wpo_wcpdf_raw_order_totals', WPO_WCPDF()->export->order->get_order_item_totals(), WPO_WCPDF()->export->order ); 
  407.  
  408. // remove the colon for every label 
  409. foreach ( $totals as $key => $total ) { 
  410. $label = $total['label']; 
  411. $colon = strrpos( $label, ':' ); 
  412. if( $colon !== false ) { 
  413. $label = substr_replace( $label, '', $colon, 1 ); 
  414. }  
  415. $totals[$key]['label'] = $label; 
  416.  
  417. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  418. if ( get_post_type( $order_id ) != 'shop_order_refund' ) { 
  419. // WC2.4 fix order_total for refunded orders 
  420. if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '>=' ) && isset($totals['order_total']) ) { 
  421. if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) { 
  422. $tax_display = get_option( 'woocommerce_tax_display_cart' ); 
  423. } else { 
  424. $tax_display = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'tax_display_cart' ); 
  425.  
  426. $totals['order_total']['value'] = wc_price( WPO_WCPDF()->export->order->get_total(), array( 'currency' => WCX_Order::get_prop( WPO_WCPDF()->export->order, 'currency' ) ) ); 
  427. $order_total = WPO_WCPDF()->export->order->get_total(); 
  428. $tax_string = ''; 
  429.  
  430. // Tax for inclusive prices 
  431. if ( wc_tax_enabled() && 'incl' == $tax_display ) { 
  432. $tax_string_array = array(); 
  433. if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) { 
  434. foreach ( WPO_WCPDF()->export->order->get_tax_totals() as $code => $tax ) { 
  435. $tax_amount = $tax->formatted_amount; 
  436. $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); 
  437. } else { 
  438. $tax_string_array[] = sprintf( '%s %s', wc_price( WPO_WCPDF()->export->order->get_total_tax() - WPO_WCPDF()->export->order->get_total_tax_refunded(), array( 'currency' => WPO_WCPDF()->export->order->get_order_currency() ) ), WC()->countries->tax_or_vat() ); 
  439. if ( ! empty( $tax_string_array ) ) { 
  440. if ( version_compare( WOOCOMMERCE_VERSION, '2.6', '>=' ) ) { 
  441. $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); 
  442. } else { 
  443. // use old capitalized string 
  444. $tax_string = ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); 
  445.  
  446. $totals['order_total']['value'] .= $tax_string; 
  447.  
  448. // remove refund lines (shouldn't be in invoice) 
  449. foreach ( $totals as $key => $total ) { 
  450. if ( strpos($key, 'refund_') !== false ) { 
  451. unset( $totals[$key] ); 
  452.  
  453.  
  454. return apply_filters( 'wpo_wcpdf_woocommerce_totals', $totals, WPO_WCPDF()->export->order ); 
  455.  
  456. /** 
  457. * Return/show the order subtotal 
  458. */ 
  459. public function get_order_subtotal( $tax = 'excl', $discount = 'incl' ) { // set $tax to 'incl' to include tax, same for $discount 
  460. //$compound = ($discount == 'incl')?true:false; 
  461. $subtotal = WPO_WCPDF()->export->order->get_subtotal_to_display( false, $tax ); 
  462.  
  463. $subtotal = ($pos = strpos($subtotal, ' <small')) ? substr($subtotal, 0, $pos) : $subtotal; //removing the 'excluding tax' text  
  464.  
  465. $subtotal = array ( 
  466. 'label' => __('Subtotal', 'wpo_wcpdf'),  
  467. 'value' => $subtotal,  
  468. ); 
  469.  
  470. return apply_filters( 'wpo_wcpdf_order_subtotal', $subtotal, $tax, $discount ); 
  471. public function order_subtotal( $tax = 'excl', $discount = 'incl' ) { 
  472. $subtotal = $this->get_order_subtotal( $tax, $discount ); 
  473. echo $subtotal['value']; 
  474.  
  475. /** 
  476. * Return/show the order shipping costs 
  477. */ 
  478. public function get_order_shipping( $tax = 'excl' ) { // set $tax to 'incl' to include tax 
  479. $shipping_cost = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'shipping_total', 'view' ); 
  480. $shipping_tax = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'shipping_tax', 'view' ); 
  481.  
  482. if ($tax == 'excl' ) { 
  483. $formatted_shipping_cost = WPO_WCPDF()->export->wc_price( $shipping_cost ); 
  484. } else { 
  485. $formatted_shipping_cost = WPO_WCPDF()->export->wc_price( $shipping_cost + $shipping_tax ); 
  486.  
  487. $shipping = array ( 
  488. 'label' => __('Shipping', 'wpo_wcpdf'),  
  489. 'value' => $formatted_shipping_cost,  
  490. 'tax' => WPO_WCPDF()->export->wc_price( $shipping_tax ),  
  491. ); 
  492. return apply_filters( 'wpo_wcpdf_order_shipping', $shipping, $tax ); 
  493. public function order_shipping( $tax = 'excl' ) { 
  494. $shipping = $this->get_order_shipping( $tax ); 
  495. echo $shipping['value']; 
  496.  
  497. /** 
  498. * Return/show the total discount 
  499. */ 
  500. public function get_order_discount( $type = 'total', $tax = 'incl' ) { 
  501. if ( $tax == 'incl' ) { 
  502. switch ($type) { 
  503. case 'cart': 
  504. // Cart Discount - pre-tax discounts. (deprecated in WC2.3) 
  505. $discount_value = WPO_WCPDF()->export->order->get_cart_discount(); 
  506. break; 
  507. case 'order': 
  508. // Order Discount - post-tax discounts. (deprecated in WC2.3) 
  509. $discount_value = WPO_WCPDF()->export->order->get_order_discount(); 
  510. break; 
  511. case 'total': 
  512. // Total Discount 
  513. if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) { 
  514. $discount_value = WPO_WCPDF()->export->order->get_total_discount( false ); // $ex_tax = false 
  515. } else { 
  516. // WC2.2 and older: recalculate to include tax 
  517. $discount_value = 0; 
  518. $items = WPO_WCPDF()->export->order->get_items();; 
  519. if( sizeof( $items ) > 0 ) { 
  520. foreach( $items as $item ) { 
  521. $discount_value += ($item['line_subtotal'] + $item['line_subtotal_tax']) - ($item['line_total'] + $item['line_tax']); 
  522.  
  523. break; 
  524. default: 
  525. // Total Discount - Cart & Order Discounts combined 
  526. $discount_value = WPO_WCPDF()->export->order->get_total_discount(); 
  527. break; 
  528. } else { // calculate discount excluding tax 
  529. if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) { 
  530. $discount_value = WPO_WCPDF()->export->order->get_total_discount( true ); // $ex_tax = true 
  531. } else { 
  532. // WC2.2 and older: recalculate to exclude tax 
  533. $discount_value = 0; 
  534.  
  535. $items = WPO_WCPDF()->export->order->get_items();; 
  536. if( sizeof( $items ) > 0 ) { 
  537. foreach( $items as $item ) { 
  538. $discount_value += ($item['line_subtotal'] - $item['line_total']); 
  539.  
  540. $discount = array ( 
  541. 'label' => __('Discount', 'wpo_wcpdf'),  
  542. 'value' => WPO_WCPDF()->export->wc_price($discount_value),  
  543. 'raw_value' => $discount_value,  
  544. ); 
  545.  
  546. if ( round( $discount_value, 3 ) != 0 ) { 
  547. return apply_filters( 'wpo_wcpdf_order_discount', $discount, $type, $tax ); 
  548. public function order_discount( $type = 'total', $tax = 'incl' ) { 
  549. $discount = $this->get_order_discount( $type, $tax ); 
  550. echo $discount['value']; 
  551.  
  552. /** 
  553. * Return the order fees 
  554. */ 
  555. public function get_order_fees( $tax = 'excl' ) { 
  556. if ( $wcfees = WPO_WCPDF()->export->order->get_fees() ) { 
  557. foreach( $wcfees as $id => $fee ) { 
  558. if ($tax == 'excl' ) { 
  559. $fee_price = WPO_WCPDF()->export->wc_price( $fee['line_total'] ); 
  560. } else { 
  561. $fee_price = WPO_WCPDF()->export->wc_price( $fee['line_total'] + $fee['line_tax'] ); 
  562.  
  563. $fees[ $id ] = array( 
  564. 'label' => $fee['name'],  
  565. 'value' => $fee_price,  
  566. 'line_total' => WPO_WCPDF()->export->wc_price($fee['line_total']),  
  567. 'line_tax' => WPO_WCPDF()->export->wc_price($fee['line_tax']) 
  568. ); 
  569. return $fees; 
  570.  
  571. /** 
  572. * Return the order taxes 
  573. */ 
  574. public function get_order_taxes() { 
  575. $tax_label = __( 'VAT', 'wpo_wcpdf' ); // register alternate label translation 
  576. $tax_label = __( 'Tax rate', 'wpo_wcpdf' ); 
  577. $tax_rate_ids = WPO_WCPDF()->export->get_tax_rate_ids(); 
  578. if (WPO_WCPDF()->export->order->get_taxes()) { 
  579. foreach ( WPO_WCPDF()->export->order->get_taxes() as $key => $tax ) { 
  580. if ( WCX::is_wc_version_gte_3_0() ) { 
  581. $taxes[ $key ] = array( 
  582. 'label' => $tax->get_label(),  
  583. 'value' => WPO_WCPDF()->export->wc_price( $tax->get_tax_total() + $tax->get_shipping_tax_total() ),  
  584. 'rate_id' => $tax->get_rate_id(),  
  585. 'tax_amount' => $tax->get_tax_total(),  
  586. 'shipping_tax_amount' => $tax->get_shipping_tax_total(),  
  587. 'rate' => isset( $tax_rate_ids[ $tax->get_rate_id() ] ) ? ( (float) $tax_rate_ids[$tax->get_rate_id()]['tax_rate'] ) . ' %': '',  
  588. ); 
  589. } else { 
  590. $taxes[ $key ] = array( 
  591. 'label' => isset( $tax[ 'label' ] ) ? $tax[ 'label' ] : $tax[ 'name' ],  
  592. 'value' => WPO_WCPDF()->export->wc_price( ( $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ] ) ),  
  593. 'rate_id' => $tax['rate_id'],  
  594. 'tax_amount' => $tax['tax_amount'],  
  595. 'shipping_tax_amount' => $tax['shipping_tax_amount'],  
  596. 'rate' => isset( $tax_rate_ids[ $tax['rate_id'] ] ) ? ( (float) $tax_rate_ids[$tax['rate_id']]['tax_rate'] ) . ' %': '',  
  597. ); 
  598.  
  599.  
  600. return apply_filters( 'wpo_wcpdf_order_taxes', $taxes ); 
  601.  
  602. /** 
  603. * Return/show the order grand total 
  604. */ 
  605. public function get_order_grand_total( $tax = 'incl' ) { 
  606. if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) { 
  607. // WC 2.1 or newer is used 
  608. $total_unformatted = WPO_WCPDF()->export->order->get_total(); 
  609. } else { 
  610. // Backwards compatibility 
  611. $total_unformatted = WPO_WCPDF()->export->order->get_order_total(); 
  612.  
  613. if ($tax == 'excl' ) { 
  614. $total = WPO_WCPDF()->export->wc_price( $total_unformatted - WPO_WCPDF()->export->order->get_total_tax() ); 
  615. $label = __( 'Total ex. VAT', 'wpo_wcpdf' ); 
  616. } else { 
  617. $total = WPO_WCPDF()->export->wc_price( ( $total_unformatted ) ); 
  618. $label = __( 'Total', 'wpo_wcpdf' ); 
  619.  
  620. $grand_total = array( 
  621. 'label' => $label,  
  622. 'value' => $total,  
  623. );  
  624.  
  625. return apply_filters( 'wpo_wcpdf_order_grand_total', $grand_total, $tax ); 
  626. public function order_grand_total( $tax = 'incl' ) { 
  627. $grand_total = $this->get_order_grand_total( $tax ); 
  628. echo $grand_total['value']; 
  629.  
  630.  
  631. /** 
  632. * Return/Show shipping notes 
  633. */ 
  634. public function get_shipping_notes() { 
  635. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  636. if ( get_post_type( $order_id ) == 'shop_order_refund' ) { 
  637. // return reason for refund if order is a refund 
  638. if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) { 
  639. $shipping_notes = WPO_WCPDF()->export->order->get_reason(); 
  640. } elseif ( method_exists(WPO_WCPDF()->export->order, 'get_refund_reason') ) { 
  641. $shipping_notes = WPO_WCPDF()->export->order->get_refund_reason(); 
  642. } else { 
  643. $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( WPO_WCPDF()->export->order, 'customer_note', 'view' ) ) ); 
  644. } else { 
  645. $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( WPO_WCPDF()->export->order, 'customer_note', 'view' ) ) ); 
  646. return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes ); 
  647. public function shipping_notes() { 
  648. echo $this->get_shipping_notes(); 
  649.  
  650.  
  651. /** 
  652. * Return/Show shop/company footer imprint, copyright etc. 
  653. */ 
  654. public function get_footer() { 
  655. if (isset(WPO_WCPDF()->settings->template_settings['footer'])) { 
  656. $footer = wpautop( wptexturize( WPO_WCPDF()->settings->template_settings[ 'footer' ] ) ); 
  657. return apply_filters( 'wpo_wcpdf_footer', $footer ); 
  658. public function footer() { 
  659. echo $this->get_footer(); 
  660.  
  661. /** 
  662. * Return/Show Extra field 1 
  663. */ 
  664. public function get_extra_1() { 
  665. if (isset(WPO_WCPDF()->settings->template_settings['extra_1'])) { 
  666. $extra_1 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_1' ] ) ); 
  667. return apply_filters( 'wpo_wcpdf_extra_1', $extra_1 ); 
  668. public function extra_1() { 
  669. echo $this->get_extra_1(); 
  670.  
  671. /** 
  672. * Return/Show Extra field 2 
  673. */ 
  674. public function get_extra_2() { 
  675. if (isset(WPO_WCPDF()->settings->template_settings['extra_2'])) { 
  676. $extra_2 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_2' ] ) ); 
  677. return apply_filters( 'wpo_wcpdf_extra_2', $extra_2 ); 
  678. public function extra_2() { 
  679. echo $this->get_extra_2(); 
  680.  
  681. /** 
  682. * Return/Show Extra field 3 
  683. */ 
  684. public function get_extra_3() { 
  685. if (isset(WPO_WCPDF()->settings->template_settings['extra_3'])) { 
  686. $extra_3 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_3' ] ) ); 
  687. return apply_filters( 'wpo_wcpdf_extra_3', $extra_3 ); 
  688. public function extra_3() { 
  689. echo $this->get_extra_3(); 
  1. class WooCommerce_PDF_Invoices_Functions { 
  2.  
  3. /** 
  4. * Get template name from slug 
  5. */ 
  6. public function get_template_name ( $template_type ) { 
  7. switch ( $template_type ) { 
  8. case 'invoice': 
  9. $template_name = apply_filters( 'wpo_wcpdf_invoice_title', __( 'Invoice', 'wpo_wcpdf' ) ); 
  10. break; 
  11. case 'packing-slip': 
  12. $template_name = apply_filters( 'wpo_wcpdf_packing_slip_title', __( 'Packing Slip', 'wpo_wcpdf' ) ); 
  13. break; 
  14. default: 
  15. // try to 'unslug' the name 
  16. $template_name = ucwords( str_replace( array( '_', '-' ), ' ', $template_type ) ); 
  17. break; 
  18.  
  19. return apply_filters( 'wpo_wcpdf_template_name', $template_name, $template_type ); 
  20.  
  21. /** 
  22. * Output template styles 
  23. */ 
  24. public function template_styles() { 
  25. $css = apply_filters( 'wpo_wcpdf_template_styles_file', WPO_WCPDF()->export->template_path. '/' .'style.css' ); 
  26.  
  27. ob_start(); 
  28. if (file_exists($css)) { 
  29. include($css); 
  30. $html = ob_get_clean(); 
  31. $html = apply_filters( 'wpo_wcpdf_template_styles', $html ); 
  32.  
  33. echo $html; 
  34.  
  35. /** 
  36. * Return logo id 
  37. */ 
  38. public function get_header_logo_id() { 
  39. if (isset(WPO_WCPDF()->settings->template_settings['header_logo'])) { 
  40. return apply_filters( 'wpo_wcpdf_header_logo_id', WPO_WCPDF()->settings->template_settings['header_logo'] ); 
  41.  
  42. /** 
  43. * Show logo html 
  44. */ 
  45. public function header_logo() { 
  46. if ($this->get_header_logo_id()) { 
  47. $attachment_id = $this->get_header_logo_id(); 
  48. $company = isset(WPO_WCPDF()->settings->template_settings['shop_name'])? WPO_WCPDF()->settings->template_settings['shop_name'] : ''; 
  49. if( $attachment_id ) { 
  50. $attachment = wp_get_attachment_image_src( $attachment_id, 'full', false ); 
  51.  
  52. $attachment_src = $attachment[0]; 
  53. $attachment_width = $attachment[1]; 
  54. $attachment_height = $attachment[2]; 
  55.  
  56. $attachment_path = get_attached_file( $attachment_id ); 
  57.  
  58. if ( apply_filters('wpo_wcpdf_use_path', true) && file_exists($attachment_path) ) { 
  59. $src = $attachment_path; 
  60. } else { 
  61. $src = $attachment_src; 
  62.  
  63. printf('<img src="%1$s" width="%2$d" height="%3$d" alt="%4$s" />', $src, $attachment_width, $attachment_height, esc_attr( $company ) ); 
  64.  
  65. /** 
  66. * Return/Show custom company name or default to blog name 
  67. */ 
  68. public function get_shop_name() { 
  69. if (!empty(WPO_WCPDF()->settings->template_settings['shop_name'])) { 
  70. $name = trim( WPO_WCPDF()->settings->template_settings['shop_name'] ); 
  71. return apply_filters( 'wpo_wcpdf_shop_name', wptexturize( $name ) ); 
  72. } else { 
  73. return apply_filters( 'wpo_wcpdf_shop_name', get_bloginfo( 'name' ) ); 
  74. public function shop_name() { 
  75. echo $this->get_shop_name(); 
  76.  
  77. /** 
  78. * Return/Show shop/company address if provided 
  79. */ 
  80. public function get_shop_address() { 
  81. $shop_address = apply_filters( 'wpo_wcpdf_shop_address', wpautop( wptexturize( WPO_WCPDF()->settings->template_settings['shop_address'] ) ) ); 
  82. if (!empty($shop_address)) { 
  83. return $shop_address; 
  84. } else { 
  85. return false; 
  86. public function shop_address() { 
  87. echo $this->get_shop_address(); 
  88.  
  89. /** 
  90. * Check if billing address and shipping address are equal 
  91. */ 
  92. public function ships_to_different_address() { 
  93. $order = &WPO_WCPDF()->export->order; 
  94. $order_id = WCX_Order::get_id( $order ); 
  95. // always prefer parent address for refunds 
  96. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  97. $current_order = $order; 
  98. $order = WCX::get_order( $parent_order_id ); 
  99.  
  100. $address_comparison_fields = apply_filters( 'wpo_wcpdf_address_comparison_fields', array( 
  101. 'first_name',  
  102. 'last_name',  
  103. 'company',  
  104. 'address_1',  
  105. 'address_2',  
  106. 'city',  
  107. 'state',  
  108. 'postcode',  
  109. 'country' 
  110. ) ); 
  111.  
  112. foreach ($address_comparison_fields as $address_field) { 
  113. $billing_field = WCX_Order::get_prop( $order, "billing_{$address_field}", 'view'); 
  114. $shipping_field = WCX_Order::get_prop( $order, "shipping_{$address_field}", 'view'); 
  115. if ( $shipping_field != $billing_field ) { 
  116. // this address field is different -> ships to different address! 
  117. $order = isset($current_order) ? $current_order : $order; // reset back to refund if necessery 
  118. return true; 
  119.  
  120. //if we got here, it means the addresses are equal -> doesn't ship to different address! 
  121. $order = isset($current_order) ? $current_order : $order; // reset back to refund if necessery 
  122. return apply_filters( 'wpo_wcpdf_ships_to_different_address', false, $order ); 
  123.  
  124. /** 
  125. * Return/Show billing address 
  126. */ 
  127. public function get_billing_address() { 
  128. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  129. // always prefer parent billing address for refunds 
  130. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  131. // temporarily switch order to make all filters / order calls work correctly 
  132. $current_order = WPO_WCPDF()->export->order; 
  133. WPO_WCPDF()->export->order = WCX::get_order( $parent_order_id ); 
  134. $address = apply_filters( 'wpo_wcpdf_billing_address', WPO_WCPDF()->export->order->get_formatted_billing_address() ); 
  135. // switch back & unset 
  136. WPO_WCPDF()->export->order = $current_order; 
  137. unset($current_order); 
  138. } elseif ( $address = WPO_WCPDF()->export->order->get_formatted_billing_address() ) { 
  139. // regular shop_order 
  140. $address = apply_filters( 'wpo_wcpdf_billing_address', $address ); 
  141. } else { 
  142. // no address 
  143. $address = apply_filters( 'wpo_wcpdf_billing_address', __('N/A', 'wpo_wcpdf') ); 
  144.  
  145. return $address; 
  146. public function billing_address() { 
  147. echo $this->get_billing_address(); 
  148.  
  149. /** 
  150. * Return/Show billing email 
  151. */ 
  152. public function get_billing_email() { 
  153. $billing_email = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'billing_email', 'view' ); 
  154.  
  155. if ( !$billing_email && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  156. // try parent 
  157. $parent_order = WCX::get_order( $parent_order_id ); 
  158. $billing_email = WCX_Order::get_prop( $parent_order, 'billing_email', 'view' ); 
  159.  
  160. return apply_filters( 'wpo_wcpdf_billing_email', $billing_email ); 
  161. public function billing_email() { 
  162. echo $this->get_billing_email(); 
  163.  
  164. /** 
  165. * Return/Show billing phone 
  166. */ 
  167. public function get_billing_phone() { 
  168. $billing_phone = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'billing_phone', 'view' ); 
  169.  
  170. if ( !$billing_phone && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  171. // try parent 
  172. $parent_order = WCX::get_order( $parent_order_id ); 
  173. $billing_phone = WCX_Order::get_prop( $parent_order, 'billing_phone', 'view' ); 
  174.  
  175. return apply_filters( 'wpo_wcpdf_billing_phone', $billing_phone ); 
  176. public function billing_phone() { 
  177. echo $this->get_billing_phone(); 
  178.  
  179. /** 
  180. * Return/Show shipping address 
  181. */ 
  182. public function get_shipping_address() { 
  183. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  184.  
  185. // always prefer parent shipping address for refunds 
  186. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  187. // temporarily switch order to make all filters / order calls work correctly 
  188. $current_order = WPO_WCPDF()->export->order; 
  189. WPO_WCPDF()->export->order = WCX::get_order( $parent_order_id ); 
  190. $address = apply_filters( 'wpo_wcpdf_shipping_address', WPO_WCPDF()->export->order->get_formatted_shipping_address() ); 
  191. // switch back & unset 
  192. WPO_WCPDF()->export->order = $current_order; 
  193. unset($current_order); 
  194. } elseif ( $address = WPO_WCPDF()->export->order->get_formatted_shipping_address() ) { 
  195. // regular shop_order 
  196. $address = apply_filters( 'wpo_wcpdf_shipping_address', $address ); 
  197. } else { 
  198. // no address 
  199. $address = apply_filters( 'wpo_wcpdf_shipping_address', __('N/A', 'wpo_wcpdf') ); 
  200.  
  201. return $address; 
  202. public function shipping_address() { 
  203. echo $this->get_shipping_address(); 
  204.  
  205. /** 
  206. * Return/Show a custom field 
  207. */  
  208. public function get_custom_field( $field_name ) { 
  209. $custom_field = WCX_Order::get_meta( WPO_WCPDF()->export->order, $field_name, true ); 
  210.  
  211. if ( !$custom_field && $parent_order_id = wp_get_post_parent_id( WCX_Order::get_id( WPO_WCPDF()->export->order ) ) ) { 
  212. // try parent 
  213. $parent_order = WCX::get_order( $parent_order_id ); 
  214. $custom_field = WCX_Order::get_meta( $parent_order, $field_name, true ); 
  215.  
  216. return apply_filters( 'wpo_wcpdf_billing_custom_field', $custom_field ); 
  217. public function custom_field( $field_name, $field_label = '', $display_empty = false ) { 
  218. $custom_field = $this->get_custom_field( $field_name ); 
  219. if (!empty($field_label)) { 
  220. // add a a trailing space to the label 
  221. $field_label .= ' '; 
  222.  
  223. if (!empty($custom_field) || $display_empty) { 
  224. echo $field_label . nl2br ($custom_field); 
  225.  
  226. /** 
  227. * Return/Show order notes 
  228. */  
  229. public function get_order_notes( $filter = 'customer' ) { 
  230. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  231. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  232. $post_id = $parent_order_id; 
  233. } else { 
  234. $post_id = $order_id; 
  235.  
  236. $args = array( 
  237. 'post_id' => $post_id,  
  238. 'approve' => 'approve',  
  239. 'type' => 'order_note' 
  240. ); 
  241.  
  242. remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  243.  
  244. $notes = get_comments( $args ); 
  245.  
  246. add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ), 10, 1 ); 
  247.  
  248. if ( $notes ) { 
  249. foreach( $notes as $key => $note ) { 
  250. if ( $filter == 'customer' && !get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ) { 
  251. unset($notes[$key]); 
  252. if ( $filter == 'private' && get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ) { 
  253. unset($notes[$key]); 
  254. }  
  255. return $notes; 
  256. public function order_notes( $filter = 'customer' ) { 
  257. $notes = $this->get_order_notes( $filter ); 
  258. if ( $notes ) { 
  259. foreach( $notes as $note ) { 
  260. ?> 
  261. <div class="note_content"> 
  262. <?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?> 
  263. </div> 
  264. <?php 
  265.  
  266. /** 
  267. * Return/Show the current date 
  268. */ 
  269. public function get_current_date() { 
  270. return apply_filters( 'wpo_wcpdf_date', date_i18n( get_option( 'date_format' ) ) ); 
  271. public function current_date() { 
  272. echo $this->get_current_date(); 
  273.  
  274. /** 
  275. * Return/Show payment method  
  276. */ 
  277. public function get_payment_method() { 
  278. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  279. $payment_method_label = __( 'Payment method', 'wpo_wcpdf' ); 
  280.  
  281. // use parent for credit notes 
  282. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  283. $parent_order = WCX::get_order( $parent_order_id ); 
  284. $payment_method_title = WCX_Order::get_prop( $parent_order, 'payment_method_title', 'view' ); 
  285. $payment_method = __( $payment_method_title, 'woocommerce' ); 
  286. } else { 
  287. $payment_method_title = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'payment_method_title', 'view' ); 
  288.  
  289. $payment_method = __( $payment_method_title, 'woocommerce' ); 
  290.  
  291. return apply_filters( 'wpo_wcpdf_payment_method', $payment_method ); 
  292. public function payment_method() { 
  293. echo $this->get_payment_method(); 
  294.  
  295. /** 
  296. * Return/Show shipping method  
  297. */ 
  298. public function get_shipping_method() { 
  299. $shipping_method_label = __( 'Shipping method', 'wpo_wcpdf' ); 
  300. return apply_filters( 'wpo_wcpdf_shipping_method', __( WPO_WCPDF()->export->order->get_shipping_method(), 'woocommerce' ) ); 
  301. public function shipping_method() { 
  302. echo $this->get_shipping_method(); 
  303.  
  304. /** 
  305. * Return/Show order number 
  306. */ 
  307. public function get_order_number() { 
  308. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  309. // try parent first 
  310. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  311. $parent_order = WCX::get_order( $parent_order_id ); 
  312. $order_number = $parent_order->get_order_number(); 
  313. } else { 
  314. $order_number = WPO_WCPDF()->export->order->get_order_number(); 
  315.  
  316. // Trim the hash to have a clean number but still  
  317. // support any filters that were applied before. 
  318. $order_number = ltrim($order_number, '#'); 
  319. return apply_filters( 'wpo_wcpdf_order_number', $order_number); 
  320. public function order_number() { 
  321. echo $this->get_order_number(); 
  322.  
  323. /** 
  324. * Return/Show invoice number  
  325. */ 
  326. public function get_invoice_number() { 
  327. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  328. // try parent first 
  329. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  330. $invoice_number = WPO_WCPDF()->export->get_invoice_number( $parent_order_id ); 
  331. } else { 
  332. $invoice_number = WPO_WCPDF()->export->get_invoice_number( $order_id ); 
  333.  
  334. return $invoice_number; 
  335. public function invoice_number() { 
  336. echo $this->get_invoice_number(); 
  337.  
  338. /** 
  339. * Return/Show the order date 
  340. */ 
  341. public function get_order_date() { 
  342. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  343. // try parent first 
  344. if ( get_post_type( $order_id ) == 'shop_order_refund' && $parent_order_id = wp_get_post_parent_id( $order_id ) ) { 
  345. $parent_order = WCX::get_order( $parent_order_id ); 
  346. $order_date = WCX_Order::get_prop( $parent_order, 'date_created' ); 
  347. } else { 
  348. $order_date = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'date_created' ); 
  349.  
  350. $date = $order_date->date_i18n( get_option( 'date_format' ) ); 
  351. $mysql_date = $order_date->date( "Y-m-d H:i:s" ); 
  352. return apply_filters( 'wpo_wcpdf_order_date', $date, $mysql_date ); 
  353. public function order_date() { 
  354. echo $this->get_order_date(); 
  355.  
  356. /** 
  357. * Return/Show the invoice date 
  358. */ 
  359. public function get_invoice_date() { 
  360. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  361. $invoice_date = WPO_WCPDF()->export->get_invoice_date( $order_id ); 
  362. return $invoice_date; 
  363. public function invoice_date() { 
  364. echo $this->get_invoice_date(); 
  365.  
  366. /** 
  367. * Return the order items 
  368. */ 
  369. public function get_order_items() { 
  370. return apply_filters( 'wpo_wcpdf_order_items', WPO_WCPDF()->export->get_order_items() ); 
  371.  
  372. /** 
  373. * Return/show product attribute 
  374. */ 
  375. public function get_product_attribute( $attribute_name, $product ) { 
  376. // first, check the text attributes 
  377. $attributes = $product->get_attributes(); 
  378. $attribute_key = @wc_attribute_taxonomy_name( $attribute_name ); 
  379. if (array_key_exists( sanitize_title( $attribute_name ), $attributes) ) { 
  380. $attribute = $product->get_attribute ( $attribute_name ); 
  381. return $attribute; 
  382. } elseif (array_key_exists( sanitize_title( $attribute_key ), $attributes) ) { 
  383. $attribute = $product->get_attribute ( $attribute_key ); 
  384. return $attribute; 
  385.  
  386. // not a text attribute, try attribute taxonomy 
  387. $attribute_key = @wc_attribute_taxonomy_name( $attribute_name ); 
  388. $product_id = WCX_Product::get_prop($product, 'id'); 
  389. $product_terms = @wc_get_product_terms( $product_id, $attribute_key, array( 'fields' => 'names' ) ); 
  390. // check if not empty, then display 
  391. if ( !empty($product_terms) ) { 
  392. $attribute = array_shift( $product_terms ); 
  393. return $attribute; 
  394. } else { 
  395. // no attribute under this name 
  396. return false; 
  397. public function product_attribute( $attribute_name, $product ) { 
  398. echo $this->get_product_attribute( $attribute_name, $product ); 
  399.  
  400.  
  401. /** 
  402. * Return the order totals listing 
  403. */ 
  404. public function get_woocommerce_totals() { 
  405. // get totals and remove the semicolon 
  406. $totals = apply_filters( 'wpo_wcpdf_raw_order_totals', WPO_WCPDF()->export->order->get_order_item_totals(), WPO_WCPDF()->export->order ); 
  407.  
  408. // remove the colon for every label 
  409. foreach ( $totals as $key => $total ) { 
  410. $label = $total['label']; 
  411. $colon = strrpos( $label, ':' ); 
  412. if( $colon !== false ) { 
  413. $label = substr_replace( $label, '', $colon, 1 ); 
  414. }  
  415. $totals[$key]['label'] = $label; 
  416.  
  417. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  418. if ( get_post_type( $order_id ) != 'shop_order_refund' ) { 
  419. // WC2.4 fix order_total for refunded orders 
  420. if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '>=' ) && isset($totals['order_total']) ) { 
  421. if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) { 
  422. $tax_display = get_option( 'woocommerce_tax_display_cart' ); 
  423. } else { 
  424. $tax_display = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'tax_display_cart' ); 
  425.  
  426. $totals['order_total']['value'] = wc_price( WPO_WCPDF()->export->order->get_total(), array( 'currency' => WCX_Order::get_prop( WPO_WCPDF()->export->order, 'currency' ) ) ); 
  427. $order_total = WPO_WCPDF()->export->order->get_total(); 
  428. $tax_string = ''; 
  429.  
  430. // Tax for inclusive prices 
  431. if ( wc_tax_enabled() && 'incl' == $tax_display ) { 
  432. $tax_string_array = array(); 
  433. if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) { 
  434. foreach ( WPO_WCPDF()->export->order->get_tax_totals() as $code => $tax ) { 
  435. $tax_amount = $tax->formatted_amount; 
  436. $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); 
  437. } else { 
  438. $tax_string_array[] = sprintf( '%s %s', wc_price( WPO_WCPDF()->export->order->get_total_tax() - WPO_WCPDF()->export->order->get_total_tax_refunded(), array( 'currency' => WPO_WCPDF()->export->order->get_order_currency() ) ), WC()->countries->tax_or_vat() ); 
  439. if ( ! empty( $tax_string_array ) ) { 
  440. if ( version_compare( WOOCOMMERCE_VERSION, '2.6', '>=' ) ) { 
  441. $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); 
  442. } else { 
  443. // use old capitalized string 
  444. $tax_string = ' ' . sprintf( __( '(Includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); 
  445.  
  446. $totals['order_total']['value'] .= $tax_string; 
  447.  
  448. // remove refund lines (shouldn't be in invoice) 
  449. foreach ( $totals as $key => $total ) { 
  450. if ( strpos($key, 'refund_') !== false ) { 
  451. unset( $totals[$key] ); 
  452.  
  453.  
  454. return apply_filters( 'wpo_wcpdf_woocommerce_totals', $totals, WPO_WCPDF()->export->order ); 
  455.  
  456. /** 
  457. * Return/show the order subtotal 
  458. */ 
  459. public function get_order_subtotal( $tax = 'excl', $discount = 'incl' ) { // set $tax to 'incl' to include tax, same for $discount 
  460. //$compound = ($discount == 'incl')?true:false; 
  461. $subtotal = WPO_WCPDF()->export->order->get_subtotal_to_display( false, $tax ); 
  462.  
  463. $subtotal = ($pos = strpos($subtotal, ' <small')) ? substr($subtotal, 0, $pos) : $subtotal; //removing the 'excluding tax' text  
  464.  
  465. $subtotal = array ( 
  466. 'label' => __('Subtotal', 'wpo_wcpdf'),  
  467. 'value' => $subtotal,  
  468. ); 
  469.  
  470. return apply_filters( 'wpo_wcpdf_order_subtotal', $subtotal, $tax, $discount ); 
  471. public function order_subtotal( $tax = 'excl', $discount = 'incl' ) { 
  472. $subtotal = $this->get_order_subtotal( $tax, $discount ); 
  473. echo $subtotal['value']; 
  474.  
  475. /** 
  476. * Return/show the order shipping costs 
  477. */ 
  478. public function get_order_shipping( $tax = 'excl' ) { // set $tax to 'incl' to include tax 
  479. $shipping_cost = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'shipping_total', 'view' ); 
  480. $shipping_tax = WCX_Order::get_prop( WPO_WCPDF()->export->order, 'shipping_tax', 'view' ); 
  481.  
  482. if ($tax == 'excl' ) { 
  483. $formatted_shipping_cost = WPO_WCPDF()->export->wc_price( $shipping_cost ); 
  484. } else { 
  485. $formatted_shipping_cost = WPO_WCPDF()->export->wc_price( $shipping_cost + $shipping_tax ); 
  486.  
  487. $shipping = array ( 
  488. 'label' => __('Shipping', 'wpo_wcpdf'),  
  489. 'value' => $formatted_shipping_cost,  
  490. 'tax' => WPO_WCPDF()->export->wc_price( $shipping_tax ),  
  491. ); 
  492. return apply_filters( 'wpo_wcpdf_order_shipping', $shipping, $tax ); 
  493. public function order_shipping( $tax = 'excl' ) { 
  494. $shipping = $this->get_order_shipping( $tax ); 
  495. echo $shipping['value']; 
  496.  
  497. /** 
  498. * Return/show the total discount 
  499. */ 
  500. public function get_order_discount( $type = 'total', $tax = 'incl' ) { 
  501. if ( $tax == 'incl' ) { 
  502. switch ($type) { 
  503. case 'cart': 
  504. // Cart Discount - pre-tax discounts. (deprecated in WC2.3) 
  505. $discount_value = WPO_WCPDF()->export->order->get_cart_discount(); 
  506. break; 
  507. case 'order': 
  508. // Order Discount - post-tax discounts. (deprecated in WC2.3) 
  509. $discount_value = WPO_WCPDF()->export->order->get_order_discount(); 
  510. break; 
  511. case 'total': 
  512. // Total Discount 
  513. if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) { 
  514. $discount_value = WPO_WCPDF()->export->order->get_total_discount( false ); // $ex_tax = false 
  515. } else { 
  516. // WC2.2 and older: recalculate to include tax 
  517. $discount_value = 0; 
  518. $items = WPO_WCPDF()->export->order->get_items();; 
  519. if( sizeof( $items ) > 0 ) { 
  520. foreach( $items as $item ) { 
  521. $discount_value += ($item['line_subtotal'] + $item['line_subtotal_tax']) - ($item['line_total'] + $item['line_tax']); 
  522.  
  523. break; 
  524. default: 
  525. // Total Discount - Cart & Order Discounts combined 
  526. $discount_value = WPO_WCPDF()->export->order->get_total_discount(); 
  527. break; 
  528. } else { // calculate discount excluding tax 
  529. if ( version_compare( WOOCOMMERCE_VERSION, '2.3' ) >= 0 ) { 
  530. $discount_value = WPO_WCPDF()->export->order->get_total_discount( true ); // $ex_tax = true 
  531. } else { 
  532. // WC2.2 and older: recalculate to exclude tax 
  533. $discount_value = 0; 
  534.  
  535. $items = WPO_WCPDF()->export->order->get_items();; 
  536. if( sizeof( $items ) > 0 ) { 
  537. foreach( $items as $item ) { 
  538. $discount_value += ($item['line_subtotal'] - $item['line_total']); 
  539.  
  540. $discount = array ( 
  541. 'label' => __('Discount', 'wpo_wcpdf'),  
  542. 'value' => WPO_WCPDF()->export->wc_price($discount_value),  
  543. 'raw_value' => $discount_value,  
  544. ); 
  545.  
  546. if ( round( $discount_value, 3 ) != 0 ) { 
  547. return apply_filters( 'wpo_wcpdf_order_discount', $discount, $type, $tax ); 
  548. public function order_discount( $type = 'total', $tax = 'incl' ) { 
  549. $discount = $this->get_order_discount( $type, $tax ); 
  550. echo $discount['value']; 
  551.  
  552. /** 
  553. * Return the order fees 
  554. */ 
  555. public function get_order_fees( $tax = 'excl' ) { 
  556. if ( $wcfees = WPO_WCPDF()->export->order->get_fees() ) { 
  557. foreach( $wcfees as $id => $fee ) { 
  558. if ($tax == 'excl' ) { 
  559. $fee_price = WPO_WCPDF()->export->wc_price( $fee['line_total'] ); 
  560. } else { 
  561. $fee_price = WPO_WCPDF()->export->wc_price( $fee['line_total'] + $fee['line_tax'] ); 
  562.  
  563. $fees[ $id ] = array( 
  564. 'label' => $fee['name'],  
  565. 'value' => $fee_price,  
  566. 'line_total' => WPO_WCPDF()->export->wc_price($fee['line_total']),  
  567. 'line_tax' => WPO_WCPDF()->export->wc_price($fee['line_tax']) 
  568. ); 
  569. return $fees; 
  570.  
  571. /** 
  572. * Return the order taxes 
  573. */ 
  574. public function get_order_taxes() { 
  575. $tax_label = __( 'VAT', 'wpo_wcpdf' ); // register alternate label translation 
  576. $tax_label = __( 'Tax rate', 'wpo_wcpdf' ); 
  577. $tax_rate_ids = WPO_WCPDF()->export->get_tax_rate_ids(); 
  578. if (WPO_WCPDF()->export->order->get_taxes()) { 
  579. foreach ( WPO_WCPDF()->export->order->get_taxes() as $key => $tax ) { 
  580. if ( WCX::is_wc_version_gte_3_0() ) { 
  581. $taxes[ $key ] = array( 
  582. 'label' => $tax->get_label(),  
  583. 'value' => WPO_WCPDF()->export->wc_price( $tax->get_tax_total() + $tax->get_shipping_tax_total() ),  
  584. 'rate_id' => $tax->get_rate_id(),  
  585. 'tax_amount' => $tax->get_tax_total(),  
  586. 'shipping_tax_amount' => $tax->get_shipping_tax_total(),  
  587. 'rate' => isset( $tax_rate_ids[ $tax->get_rate_id() ] ) ? ( (float) $tax_rate_ids[$tax->get_rate_id()]['tax_rate'] ) . ' %': '',  
  588. ); 
  589. } else { 
  590. $taxes[ $key ] = array( 
  591. 'label' => isset( $tax[ 'label' ] ) ? $tax[ 'label' ] : $tax[ 'name' ],  
  592. 'value' => WPO_WCPDF()->export->wc_price( ( $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ] ) ),  
  593. 'rate_id' => $tax['rate_id'],  
  594. 'tax_amount' => $tax['tax_amount'],  
  595. 'shipping_tax_amount' => $tax['shipping_tax_amount'],  
  596. 'rate' => isset( $tax_rate_ids[ $tax['rate_id'] ] ) ? ( (float) $tax_rate_ids[$tax['rate_id']]['tax_rate'] ) . ' %': '',  
  597. ); 
  598.  
  599.  
  600. return apply_filters( 'wpo_wcpdf_order_taxes', $taxes ); 
  601.  
  602. /** 
  603. * Return/show the order grand total 
  604. */ 
  605. public function get_order_grand_total( $tax = 'incl' ) { 
  606. if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) { 
  607. // WC 2.1 or newer is used 
  608. $total_unformatted = WPO_WCPDF()->export->order->get_total(); 
  609. } else { 
  610. // Backwards compatibility 
  611. $total_unformatted = WPO_WCPDF()->export->order->get_order_total(); 
  612.  
  613. if ($tax == 'excl' ) { 
  614. $total = WPO_WCPDF()->export->wc_price( $total_unformatted - WPO_WCPDF()->export->order->get_total_tax() ); 
  615. $label = __( 'Total ex. VAT', 'wpo_wcpdf' ); 
  616. } else { 
  617. $total = WPO_WCPDF()->export->wc_price( ( $total_unformatted ) ); 
  618. $label = __( 'Total', 'wpo_wcpdf' ); 
  619.  
  620. $grand_total = array( 
  621. 'label' => $label,  
  622. 'value' => $total,  
  623. );  
  624.  
  625. return apply_filters( 'wpo_wcpdf_order_grand_total', $grand_total, $tax ); 
  626. public function order_grand_total( $tax = 'incl' ) { 
  627. $grand_total = $this->get_order_grand_total( $tax ); 
  628. echo $grand_total['value']; 
  629.  
  630.  
  631. /** 
  632. * Return/Show shipping notes 
  633. */ 
  634. public function get_shipping_notes() { 
  635. $order_id = WCX_Order::get_id( WPO_WCPDF()->export->order ); 
  636. if ( get_post_type( $order_id ) == 'shop_order_refund' ) { 
  637. // return reason for refund if order is a refund 
  638. if ( version_compare( WOOCOMMERCE_VERSION, '3.0', '>=' ) ) { 
  639. $shipping_notes = WPO_WCPDF()->export->order->get_reason(); 
  640. } elseif ( method_exists(WPO_WCPDF()->export->order, 'get_refund_reason') ) { 
  641. $shipping_notes = WPO_WCPDF()->export->order->get_refund_reason(); 
  642. } else { 
  643. $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( WPO_WCPDF()->export->order, 'customer_note', 'view' ) ) ); 
  644. } else { 
  645. $shipping_notes = wpautop( wptexturize( WCX_Order::get_prop( WPO_WCPDF()->export->order, 'customer_note', 'view' ) ) ); 
  646. return apply_filters( 'wpo_wcpdf_shipping_notes', $shipping_notes ); 
  647. public function shipping_notes() { 
  648. echo $this->get_shipping_notes(); 
  649.  
  650.  
  651. /** 
  652. * Return/Show shop/company footer imprint, copyright etc. 
  653. */ 
  654. public function get_footer() { 
  655. if (isset(WPO_WCPDF()->settings->template_settings['footer'])) { 
  656. $footer = wpautop( wptexturize( WPO_WCPDF()->settings->template_settings[ 'footer' ] ) ); 
  657. return apply_filters( 'wpo_wcpdf_footer', $footer ); 
  658. public function footer() { 
  659. echo $this->get_footer(); 
  660.  
  661. /** 
  662. * Return/Show Extra field 1 
  663. */ 
  664. public function get_extra_1() { 
  665. if (isset(WPO_WCPDF()->settings->template_settings['extra_1'])) { 
  666. $extra_1 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_1' ] ) ); 
  667. return apply_filters( 'wpo_wcpdf_extra_1', $extra_1 ); 
  668. public function extra_1() { 
  669. echo $this->get_extra_1(); 
  670.  
  671. /** 
  672. * Return/Show Extra field 2 
  673. */ 
  674. public function get_extra_2() { 
  675. if (isset(WPO_WCPDF()->settings->template_settings['extra_2'])) { 
  676. $extra_2 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_2' ] ) ); 
  677. return apply_filters( 'wpo_wcpdf_extra_2', $extra_2 ); 
  678. public function extra_2() { 
  679. echo $this->get_extra_2(); 
  680.  
  681. /** 
  682. * Return/Show Extra field 3 
  683. */ 
  684. public function get_extra_3() { 
  685. if (isset(WPO_WCPDF()->settings->template_settings['extra_3'])) { 
  686. $extra_3 = nl2br( wptexturize( WPO_WCPDF()->settings->template_settings[ 'extra_3' ] ) ); 
  687. return apply_filters( 'wpo_wcpdf_extra_3', $extra_3 ); 
  688. public function extra_3() { 
  689. echo $this->get_extra_3();