WooCommerce PDF Invoices - Version 2.5.3

Version Description

  • January 9, 2017 =

  • Added: Option to show shipping address and do not show shipping address when order has only virtual products.

  • Fixed: Reset counter option.

  • Fixed: Settings sidebar font color conflicts.

  • Fixed: Invoice number column on Shop Order page always visible.

Download this release

Release Info

Developer baaaaas
Plugin Icon 128x128 WooCommerce PDF Invoices
Version 2.5.3
Comparing to
See all releases

Code changes from version 2.5.2 to 2.5.3

assets/css/admin.css CHANGED
@@ -102,7 +102,7 @@ form.bewpi-settings-form {
102
  }
103
  .bewpi-sidebar.premium {
104
  background: #222;
105
- color: #ccc;
106
  }
107
  .bewpi-sidebar.support .btn {
108
  margin: 10px 10px 10px 0;
102
  }
103
  .bewpi-sidebar.premium {
104
  background: #222;
105
+ color: #ccc !important;
106
  }
107
  .bewpi-sidebar.support .btn {
108
  margin: 10px 10px 10px 0;
bootstrap.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WooCommerce PDF Invoices
4
  * Plugin URI: https://wordpress.org/plugins/woocommerce-pdf-invoices
5
  * Description: Automatically generate and attach customizable PDF Invoices to WooCommerce emails and connect with Dropbox, Google Drive, OneDrive or Egnyte.
6
- * Version: 2.5.2
7
  * Author: Bas Elbers
8
  * Author URI: http://wcpdfinvoices.com
9
  * License: GPL-2.0+
@@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
16
  exit;
17
  }
18
 
19
- define( 'BEWPI_VERSION', '2.5.2' );
20
 
21
  /**
22
  * Load WooCommerce PDF Invoices plugin.
3
  * Plugin Name: WooCommerce PDF Invoices
4
  * Plugin URI: https://wordpress.org/plugins/woocommerce-pdf-invoices
5
  * Description: Automatically generate and attach customizable PDF Invoices to WooCommerce emails and connect with Dropbox, Google Drive, OneDrive or Egnyte.
6
+ * Version: 2.5.3
7
  * Author: Bas Elbers
8
  * Author URI: http://wcpdfinvoices.com
9
  * License: GPL-2.0+
16
  exit;
17
  }
18
 
19
+ define( 'BEWPI_VERSION', '2.5.3' );
20
 
21
  /**
22
  * Load WooCommerce PDF Invoices plugin.
includes/abstracts/abstract-bewpi-invoice.php CHANGED
@@ -82,12 +82,6 @@ if ( ! class_exists( 'BEWPI_Abstract_Invoice' ) ) {
82
  protected $template_dir_name;
83
 
84
  /**
85
- * Next invoice counter reset enabling
86
- * @var bool
87
- */
88
- protected $counter_reset = false;
89
-
90
- /***
91
  * BEWPI_Abstract_Invoice constructor.
92
  *
93
  * @param $order_id
@@ -205,116 +199,123 @@ if ( ! class_exists( 'BEWPI_Abstract_Invoice' ) ) {
205
  return $html_sections;
206
  }
207
 
 
 
 
208
  private function delete_pdf_invoices() {
209
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
 
210
  $current_year = (int) date_i18n( 'Y', current_time( 'timestamp' ) );
211
  $bewpi_invoices_dir = BEWPI_INVOICES_DIR . $current_year . '/*.pdf';
212
  } else {
 
213
  $bewpi_invoices_dir = BEWPI_INVOICES_DIR . '*.pdf';
214
  }
215
 
216
  $files = glob( $bewpi_invoices_dir );
217
  foreach ( $files as $file ) {
218
  if ( is_file( $file ) ) {
219
- unlink( $file );
220
  }
221
  }
222
  }
223
 
 
 
 
224
  private function delete_invoice_meta() {
225
  global $wpdb;
226
 
227
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
228
- // delete all by year
229
  $query = $wpdb->prepare(
230
- "
231
- DELETE pm2 FROM $wpdb->postmeta pm1
232
  INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
233
  WHERE pm1.meta_key = '%s'
234
  AND pm1.meta_value = %d
235
- AND (pm2.meta_key LIKE '%s' OR pm2.meta_key LIKE '%s')
236
- ",
237
- "_bewpi_invoice_year",
238
  (int) date_i18n( 'Y', current_time( 'timestamp' ) ),
239
- "_bewpi_invoice_%",
240
- "_bewpi_formatted_%"
241
  );
242
  } else {
243
- // delete all
244
  $query = $wpdb->prepare(
245
- "
246
- DELETE FROM $wpdb->postmeta
247
  WHERE meta_key = '%s'
248
  OR meta_key = '%s'
249
  OR meta_key = '%s'
250
- OR meta_key = '%s'
251
- ",
252
- "_bewpi_invoice_number",
253
- "_bewpi_formatted_invoice_number",
254
- "_bewpi_invoice_date",
255
- "_bewpi_invoice_year"
256
  );
257
  }
258
 
259
  $wpdb->query( $query );
260
  }
261
 
 
 
 
 
 
262
  private function get_next_invoice_number() {
263
- // check if user uses the built in WooCommerce order numbers
264
- if ( $this->template_options['bewpi_invoice_number_type'] !== "sequential_number" ) {
265
- return $this->order->get_order_number();
266
  }
267
 
268
- // check if user did a counter reset
269
  if ( $this->template_options['bewpi_reset_counter'] && $this->template_options['bewpi_next_invoice_number'] > 0 ) {
270
- $this->counter_reset = true;
271
-
272
  $this->delete_pdf_invoices();
273
  $this->delete_invoice_meta();
274
 
275
- // uncheck option to actually change the value
276
  $this->template_options['bewpi_reset_counter'] = 0;
277
  update_option( 'bewpi_template_settings', $this->template_options );
278
 
279
  return $this->template_options['bewpi_next_invoice_number'];
280
  }
281
 
282
- $last_invoice_number = $this->get_max_invoice_number();
283
-
284
- return ( empty( $last_invoice_number ) ) ? 1 : (int) $last_invoice_number + 1;
285
  }
286
 
 
 
 
 
 
287
  public function get_max_invoice_number() {
288
  global $wpdb;
289
 
290
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
291
- // get all by year
292
  $query = $wpdb->prepare(
293
- "
294
- SELECT max(cast(pm2.meta_value as unsigned)) as last_invoice_number
295
  FROM $wpdb->postmeta pm1 INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
296
  WHERE pm1.meta_key = '%s'
297
  AND pm1.meta_value = %d
298
- AND pm2.meta_key = '%s';
299
- ",
300
- "_bewpi_invoice_year",
301
  (int) date_i18n( 'Y', current_time( 'timestamp' ) ),
302
- "_bewpi_invoice_number"
303
  );
304
  } else {
305
- // get all
306
  $query = $wpdb->prepare(
307
- "
308
- SELECT max(cast(pm2.meta_value as unsigned)) as last_invoice_number
309
  FROM $wpdb->postmeta pm1 INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
310
- WHERE pm1.meta_key = '%s' AND pm2.meta_key = '%s';
311
- ",
312
- "_bewpi_invoice_year",
313
- "_bewpi_invoice_number"
314
  );
315
  }
316
 
317
- return $wpdb->get_var( $query );
318
  }
319
 
320
  /**
@@ -560,6 +561,11 @@ if ( ! class_exists( 'BEWPI_Abstract_Invoice' ) ) {
560
  return $str;
561
  }
562
 
 
 
 
 
 
563
  public function display_zero_rated_vat() {
564
  $is_vat_valid = get_post_meta( $this->order->id, '_vat_number_is_valid', true );
565
  if ( ! $is_vat_valid ) {
@@ -573,5 +579,29 @@ if ( ! class_exists( 'BEWPI_Abstract_Invoice' ) ) {
573
 
574
  return true;
575
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  }
577
  }
82
  protected $template_dir_name;
83
 
84
  /**
 
 
 
 
 
 
85
  * BEWPI_Abstract_Invoice constructor.
86
  *
87
  * @param $order_id
199
  return $html_sections;
200
  }
201
 
202
+ /**
203
+ * Delete invoice PDF files.
204
+ */
205
  private function delete_pdf_invoices() {
206
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
207
+ // get pdf files from year folder.
208
  $current_year = (int) date_i18n( 'Y', current_time( 'timestamp' ) );
209
  $bewpi_invoices_dir = BEWPI_INVOICES_DIR . $current_year . '/*.pdf';
210
  } else {
211
+ // get all pdf files.
212
  $bewpi_invoices_dir = BEWPI_INVOICES_DIR . '*.pdf';
213
  }
214
 
215
  $files = glob( $bewpi_invoices_dir );
216
  foreach ( $files as $file ) {
217
  if ( is_file( $file ) ) {
218
+ wp_delete_file( $file );
219
  }
220
  }
221
  }
222
 
223
+ /**
224
+ * Delete invoice post meta information.
225
+ */
226
  private function delete_invoice_meta() {
227
  global $wpdb;
228
 
229
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
230
+ // delete by year.
231
  $query = $wpdb->prepare(
232
+ "DELETE pm2 FROM $wpdb->postmeta pm1
 
233
  INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
234
  WHERE pm1.meta_key = '%s'
235
  AND pm1.meta_value = %d
236
+ AND (pm2.meta_key LIKE '%s' OR pm2.meta_key LIKE '%s')",
237
+ '_bewpi_invoice_year',
 
238
  (int) date_i18n( 'Y', current_time( 'timestamp' ) ),
239
+ '_bewpi_invoice_%',
240
+ '_bewpi_formatted_%'
241
  );
242
  } else {
243
+ // delete all.
244
  $query = $wpdb->prepare(
245
+ "DELETE FROM $wpdb->postmeta
 
246
  WHERE meta_key = '%s'
247
  OR meta_key = '%s'
248
  OR meta_key = '%s'
249
+ OR meta_key = '%s'",
250
+ '_bewpi_invoice_number',
251
+ '_bewpi_formatted_invoice_number',
252
+ '_bewpi_invoice_date',
253
+ '_bewpi_invoice_year'
 
254
  );
255
  }
256
 
257
  $wpdb->query( $query );
258
  }
259
 
260
+ /**
261
+ * Get next invoice number from db.
262
+ *
263
+ * @return int
264
+ */
265
  private function get_next_invoice_number() {
266
+ // uses WooCommerce order numbers as invoice numbers?
267
+ if ( 'sequential_number' !== $this->template_options['bewpi_invoice_number_type'] ) {
268
+ return (int) $this->order->get_order_number();
269
  }
270
 
271
+ // check if user did a counter reset.
272
  if ( $this->template_options['bewpi_reset_counter'] && $this->template_options['bewpi_next_invoice_number'] > 0 ) {
 
 
273
  $this->delete_pdf_invoices();
274
  $this->delete_invoice_meta();
275
 
276
+ // unset option.
277
  $this->template_options['bewpi_reset_counter'] = 0;
278
  update_option( 'bewpi_template_settings', $this->template_options );
279
 
280
  return $this->template_options['bewpi_next_invoice_number'];
281
  }
282
 
283
+ $max_invoice_number = $this->get_max_invoice_number();
284
+ return $max_invoice_number + 1;
 
285
  }
286
 
287
+ /**
288
+ * Return highest invoice number.
289
+ *
290
+ * @return int
291
+ */
292
  public function get_max_invoice_number() {
293
  global $wpdb;
294
 
295
  if ( (bool) $this->template_options['bewpi_reset_counter_yearly'] ) {
296
+ // get by year.
297
  $query = $wpdb->prepare(
298
+ "SELECT max(cast(pm2.meta_value as unsigned)) as last_invoice_number
 
299
  FROM $wpdb->postmeta pm1 INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
300
  WHERE pm1.meta_key = '%s'
301
  AND pm1.meta_value = %d
302
+ AND pm2.meta_key = '%s';",
303
+ '_bewpi_invoice_year',
 
304
  (int) date_i18n( 'Y', current_time( 'timestamp' ) ),
305
+ '_bewpi_invoice_number'
306
  );
307
  } else {
308
+ // get all.
309
  $query = $wpdb->prepare(
310
+ "SELECT max(cast(pm2.meta_value as unsigned)) as last_invoice_number
 
311
  FROM $wpdb->postmeta pm1 INNER JOIN $wpdb->postmeta pm2 ON pm1.post_id = pm2.post_id
312
+ WHERE pm1.meta_key = '%s' AND pm2.meta_key = '%s';",
313
+ '_bewpi_invoice_year',
314
+ '_bewpi_invoice_number'
 
315
  );
316
  }
317
 
318
+ return intval( $wpdb->get_var( $query ) );
319
  }
320
 
321
  /**
561
  return $str;
562
  }
563
 
564
+ /**
565
+ * Checks if invoice needs to have a zero rated VAT.
566
+ *
567
+ * @return bool
568
+ */
569
  public function display_zero_rated_vat() {
570
  $is_vat_valid = get_post_meta( $this->order->id, '_vat_number_is_valid', true );
571
  if ( ! $is_vat_valid ) {
579
 
580
  return true;
581
  }
582
+
583
+ /**
584
+ * Check if order has only virtual products.
585
+ *
586
+ * @return bool
587
+ * @since 2.5.3
588
+ */
589
+ protected function has_only_virtual_products() {
590
+ $virtual_products_count = 0;
591
+ foreach ( $this->order->get_items() as $item ) {
592
+ $product_id = $item['product_id'];
593
+ $product = wc_get_product( $product_id );
594
+ // product could be removed.
595
+ if ( null === $product ) {
596
+ continue;
597
+ }
598
+
599
+ if ( $product->is_virtual() ) {
600
+ $virtual_products_count ++;
601
+ }
602
+ }
603
+
604
+ return count( $this->order->get_items() ) === $virtual_products_count;
605
+ }
606
  }
607
  }
includes/admin/settings/class-bewpi-admin-settings-template.php CHANGED
@@ -232,6 +232,18 @@ if ( ! class_exists( 'BEWPI_Template_Settings' ) ) {
232
  'desc' => __( 'Displayed in big colored bar directly after invoice total.', 'woocommerce-pdf-invoices' ),
233
  'default' => __( 'Thank you for your purchase!', 'woocommerce-pdf-invoices' ),
234
  ),
 
 
 
 
 
 
 
 
 
 
 
 
235
  array(
236
  'id' => 'bewpi-show-customer-notes',
237
  'name' => self::PREFIX . 'show_customer_notes',
@@ -319,7 +331,7 @@ if ( ! class_exists( 'BEWPI_Template_Settings' ) ) {
319
  'page' => self::SETTINGS_KEY,
320
  'section' => 'invoice_number',
321
  'type' => 'number',
322
- 'desc' => __( 'Reset the invoice counter and start counting from given invoice number.<br/><b>Note:</b> Only available for Sequential numbering. All PDF invoices will be deleted and need to be manually created again! Value will be editable by selecting checkbox.', 'woocommerce-pdf-invoices' ),
323
  'default' => 1,
324
  'attrs' => array(
325
  'disabled',
@@ -612,10 +624,9 @@ if ( ! class_exists( 'BEWPI_Template_Settings' ) ) {
612
  $output['bewpi_company_logo'] = $_POST['bewpi_company_logo'];
613
  }
614
 
615
- // invoice number.
616
- if ( ! isset( $input['bewpi_next_invoice_number'] ) ) {
617
- // reset the next invoice number so it's visible in the disabled input field.
618
- $output['bewpi_next_invoice_number'] = $template_options['bewpi_next_invoice_number'];
619
  }
620
 
621
  // return the array processing any additional functions filtered by this action.
232
  'desc' => __( 'Displayed in big colored bar directly after invoice total.', 'woocommerce-pdf-invoices' ),
233
  'default' => __( 'Thank you for your purchase!', 'woocommerce-pdf-invoices' ),
234
  ),
235
+ array(
236
+ 'id' => 'bewpi-show-ship-to',
237
+ 'name' => self::PREFIX . 'show_ship_to',
238
+ 'title' => '',
239
+ 'callback' => array( $this, 'input_callback' ),
240
+ 'page' => self::SETTINGS_KEY,
241
+ 'section' => 'body',
242
+ 'type' => 'checkbox',
243
+ 'desc' => __( 'Show customers shipping address<br/><div class="bewpi-notes">By default the customers shipping address won\'t be displayed when order has only virtual products.</div>', 'woocommerce-pdf-invoices' ),
244
+ 'class' => 'bewpi-checkbox-option-title',
245
+ 'default' => 1,
246
+ ),
247
  array(
248
  'id' => 'bewpi-show-customer-notes',
249
  'name' => self::PREFIX . 'show_customer_notes',
331
  'page' => self::SETTINGS_KEY,
332
  'section' => 'invoice_number',
333
  'type' => 'number',
334
+ 'desc' => __( 'Reset the invoice counter and start counting from given invoice number.<br/><b>Note:</b> Only available for Sequential numbering. All PDF invoices will be deleted and need to be manually created again! Value will be editable when selecting checkbox.', 'woocommerce-pdf-invoices' ),
335
  'default' => 1,
336
  'attrs' => array(
337
  'disabled',
624
  $output['bewpi_company_logo'] = $_POST['bewpi_company_logo'];
625
  }
626
 
627
+ // reset invoice number.
628
+ if ( ! empty( $input['bewpi_reset_counter'] ) && ! empty( $input['bewpi_next_invoice_number'] ) ) {
629
+ $output['bewpi_next_invoice_number'] = $input['bewpi_next_invoice_number'];
 
630
  }
631
 
632
  // return the array processing any additional functions filtered by this action.
includes/be-woocommerce-pdf-invoices.php CHANGED
@@ -152,7 +152,7 @@ if ( ! class_exists( 'BE_WooCommerce_PDF_Invoices' ) ) {
152
  public function add_invoice_number_column( $columns ) {
153
  // invoice number column enabled by user?
154
  $general_settings = get_option( 'bewpi_general_settings' );
155
- if ( ! isset( $general_settings['bewpi_invoice_number_column'] ) ) {
156
  return $columns;
157
  }
158
 
@@ -311,14 +311,14 @@ if ( ! class_exists( 'BE_WooCommerce_PDF_Invoices' ) ) {
311
  * Admin scripts
312
  */
313
  public function admin_enqueue_scripts() {
314
- wp_enqueue_script( 'bewpi_admin_settings_script', BEWPI_URL . 'assets/js/admin.js', array(), false, true );
315
  wp_localize_script( 'bewpi_admin_settings_script', 'BEWPI_AJAX', array(
316
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
317
  'deactivation_nonce' => wp_create_nonce( 'deactivation-notice' ),
318
  'dismiss_nonce' => wp_create_nonce( 'dismiss-notice' ),
319
  )
320
  );
321
- wp_register_style( 'bewpi_admin_settings_css', BEWPI_URL . 'assets/css/admin.css', false, '1.0.0' );
322
  wp_enqueue_style( 'bewpi_admin_settings_css' );
323
  }
324
 
152
  public function add_invoice_number_column( $columns ) {
153
  // invoice number column enabled by user?
154
  $general_settings = get_option( 'bewpi_general_settings' );
155
+ if ( empty( $general_settings['bewpi_invoice_number_column'] ) ) {
156
  return $columns;
157
  }
158
 
311
  * Admin scripts
312
  */
313
  public function admin_enqueue_scripts() {
314
+ wp_enqueue_script( 'bewpi_admin_settings_script', BEWPI_URL . 'assets/js/admin.js', array(), BEWPI_VERSION, true );
315
  wp_localize_script( 'bewpi_admin_settings_script', 'BEWPI_AJAX', array(
316
  'ajaxurl' => admin_url( 'admin-ajax.php' ),
317
  'deactivation_nonce' => wp_create_nonce( 'deactivation-notice' ),
318
  'dismiss_nonce' => wp_create_nonce( 'dismiss-notice' ),
319
  )
320
  );
321
+ wp_register_style( 'bewpi_admin_settings_css', BEWPI_URL . 'assets/css/admin.css', false, BEWPI_VERSION );
322
  wp_enqueue_style( 'bewpi_admin_settings_css' );
323
  }
324
 
includes/templates/invoices/simple/micro/body.php CHANGED
@@ -10,12 +10,14 @@ $is_theme_text_black = $this->template_options['bewpi_theme_text_black'];
10
  <?php echo $this->order->get_formatted_billing_address(); ?><br/>
11
  <?php if ( $this->order->billing_phone != "" ) printf( __( 'Phone: %s', 'woocommerce-pdf-invoices' ), $this->order->billing_phone ); ?>
12
  </td>
13
- <td class="address small-font" width="50%">
14
- <?php if ( $this->order->get_formatted_shipping_address() != "" ) { ?>
 
 
15
  <b><?php _e( 'Ship to', 'woocommerce-pdf-invoices' ); ?></b><br/>
16
- <?php echo $this->order->get_formatted_shipping_address(); ?>
17
- <?php } ?>
18
- </td>
19
  </tr>
20
  </tbody>
21
  </table>
10
  <?php echo $this->order->get_formatted_billing_address(); ?><br/>
11
  <?php if ( $this->order->billing_phone != "" ) printf( __( 'Phone: %s', 'woocommerce-pdf-invoices' ), $this->order->billing_phone ); ?>
12
  </td>
13
+ <?php
14
+ $formatted_shipping_address = $this->order->get_formatted_shipping_address();
15
+ if ( ! empty( $this->template_settings['bewpi_show_ship_to'] ) && ! empty( $formatted_shipping_address ) && ! $this->has_only_virtual_products() ) { ?>
16
+ <td class="address small-font" width="50%">
17
  <b><?php _e( 'Ship to', 'woocommerce-pdf-invoices' ); ?></b><br/>
18
+ <?php echo $formatted_shipping_address; ?>
19
+ </td>
20
+ <?php } ?>
21
  </tr>
22
  </tbody>
23
  </table>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: woocommerce pdf invoices, invoice, generate, pdf, woocommerce, attachment, email, completed order, customer invoice, processing order, attach, automatic, vat, rate, sequential, number
5
  Requires at least: 4.0
6
  Tested up to: 4.7
7
- Stable tag: 2.5.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -217,6 +217,13 @@ add_filter( 'bewpi_formatted_invoice_number', 'alter_formatted_invoice_number',
217
 
218
  == Changelog ==
219
 
 
 
 
 
 
 
 
220
  = 2.5.2 - January 5, 2017 =
221
 
222
  - Fixed: "Expression is not allowed as class constant value" due to PHP versions older then 5.6.
4
  Tags: woocommerce pdf invoices, invoice, generate, pdf, woocommerce, attachment, email, completed order, customer invoice, processing order, attach, automatic, vat, rate, sequential, number
5
  Requires at least: 4.0
6
  Tested up to: 4.7
7
+ Stable tag: 2.5.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
217
 
218
  == Changelog ==
219
 
220
+ = 2.5.3 - January 9, 2017 =
221
+
222
+ - Added: Option to show shipping address and do not show shipping address when order has only virtual products.
223
+ - Fixed: Reset counter option.
224
+ - Fixed: Settings sidebar font color conflicts.
225
+ - Fixed: Invoice number column on Shop Order page always visible.
226
+
227
  = 2.5.2 - January 5, 2017 =
228
 
229
  - Fixed: "Expression is not allowed as class constant value" due to PHP versions older then 5.6.