Version Description
- Feature: Sequential invoice numbers (set upon invoice creation).
- Feature: Invoice date (set upon invoice creation).
Download this release
Release Info
Developer | pomegranate |
Plugin | WooCommerce PDF Invoices & Packing Slips |
Version | 1.2.0 |
Comparing to | |
See all releases |
Code changes from version 1.1.6 to 1.2.0
- includes/class-wcpdf-export.php +61 -21
- includes/class-wcpdf-settings.php +33 -0
- readme.txt +22 -1
- woocommerce-pdf-invoices-packingslips.php +53 -9
includes/class-wcpdf-export.php
CHANGED
@@ -34,8 +34,8 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
34 |
|
35 |
$this->template_path = $this->template_settings['template_path'];
|
36 |
|
37 |
-
add_action('wp_ajax_generate_wpo_wcpdf', array($this, 'generate_pdf_ajax'));
|
38 |
-
add_filter(
|
39 |
}
|
40 |
|
41 |
/**
|
@@ -146,6 +146,8 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
146 |
}
|
147 |
|
148 |
$order_ids = (array) explode('x',$_GET['order_ids']);
|
|
|
|
|
149 |
|
150 |
// User call from my-account page
|
151 |
if ( isset( $_GET['my-account'] ) ) {
|
@@ -190,6 +192,8 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
190 |
// Generate the output
|
191 |
// $this->stream_pdf( $template_type, $order_ids, $filename );
|
192 |
|
|
|
|
|
193 |
if (apply_filters('wpo_wcpdf_output_html', false, $template_type)) {
|
194 |
// Output html to browser for debug
|
195 |
// NOTE! images will be loaded with the server path by default
|
@@ -251,6 +255,37 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
251 |
return $attachments;
|
252 |
}
|
253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
/**
|
255 |
* Return evaluated template contents
|
256 |
*/
|
@@ -294,14 +329,14 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
294 |
// Set item quantity
|
295 |
$data['quantity'] = $item['qty'];
|
296 |
|
297 |
-
// Set the
|
298 |
-
$data['line_total'] = $item['line_total'];
|
299 |
-
$data['line_tax'] = $item['line_tax'];
|
300 |
$data['tax_rates'] = $this->get_tax_rate( $item['tax_class'], $item['line_total'], $item['line_tax'] );
|
301 |
|
302 |
-
// Set the
|
303 |
-
$data['line_subtotal'] = $item['line_subtotal'];
|
304 |
-
$data['line_subtotal_tax'] = $item['line_subtotal_tax'];
|
305 |
$data['ex_price'] = $this->get_formatted_item_price ( $item, 'total', 'excl' );
|
306 |
$data['price'] = $this->get_formatted_item_price ( $item, 'total' );
|
307 |
|
@@ -376,25 +411,30 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Export' ) ) {
|
|
376 |
if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) )
|
377 |
return;
|
378 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) {
|
380 |
// WC 2.1 or newer is used
|
381 |
-
|
382 |
-
|
383 |
-
} else {
|
384 |
-
$item_price = wc_price( ($this->order->get_line_subtotal( $item, true )) / $divider, array('currency' => $this->order->get_order_currency()) );
|
385 |
-
}
|
386 |
} else {
|
387 |
-
|
388 |
-
if ( $tax_display == 'excl' ) {
|
389 |
-
$item_price = woocommerce_price( ($this->order->get_line_subtotal( $item )) / $divider );
|
390 |
-
} else {
|
391 |
-
$item_price = woocommerce_price( ($this->order->get_line_subtotal( $item, true )) / $divider );
|
392 |
-
}
|
393 |
}
|
394 |
|
395 |
-
|
396 |
-
return $item_price;
|
397 |
}
|
|
|
398 |
/**
|
399 |
* Get the tax rates/percentages for a given tax class
|
400 |
* @param string $tax_class tax class slug
|
34 |
|
35 |
$this->template_path = $this->template_settings['template_path'];
|
36 |
|
37 |
+
add_action( 'wp_ajax_generate_wpo_wcpdf', array($this, 'generate_pdf_ajax' ));
|
38 |
+
add_filter( 'woocommerce_email_attachments', array( $this, 'attach_pdf_to_email' ), 99, 3);
|
39 |
}
|
40 |
|
41 |
/**
|
146 |
}
|
147 |
|
148 |
$order_ids = (array) explode('x',$_GET['order_ids']);
|
149 |
+
// Process oldest first: reverse $order_ids array
|
150 |
+
$order_ids = array_reverse($order_ids);
|
151 |
|
152 |
// User call from my-account page
|
153 |
if ( isset( $_GET['my-account'] ) ) {
|
192 |
// Generate the output
|
193 |
// $this->stream_pdf( $template_type, $order_ids, $filename );
|
194 |
|
195 |
+
// die($this->process_template( $template_type, $order_ids )); // or use the filter switch below!
|
196 |
+
|
197 |
if (apply_filters('wpo_wcpdf_output_html', false, $template_type)) {
|
198 |
// Output html to browser for debug
|
199 |
// NOTE! images will be loaded with the server path by default
|
255 |
return $attachments;
|
256 |
}
|
257 |
|
258 |
+
public function get_invoice_number( $order_id ) {
|
259 |
+
// Based on code from WooCommerce Sequential Order Numbers
|
260 |
+
global $wpdb;
|
261 |
+
|
262 |
+
$invoice_number = get_post_meta( $order_id, '_wcpdf_invoice_number', true );
|
263 |
+
|
264 |
+
// add invoice number if it doesn't exist
|
265 |
+
if ( empty($invoice_number) || !isset($invoice_number) ) {
|
266 |
+
// attempt the query up to 3 times for a much higher success rate if it fails (due to Deadlock)
|
267 |
+
// this seems to me like the safest way to avoid order number clashes
|
268 |
+
$success = false;
|
269 |
+
for ( $i = 0; $i < 3 && ! $success; $i++ ) {
|
270 |
+
// Get maximum invoice number in the DB
|
271 |
+
$max_invoice_number = $wpdb->get_var( 'SELECT max(cast(meta_value as UNSIGNED)) from ' . $wpdb->postmeta . ' where meta_key="_wcpdf_invoice_number"' );
|
272 |
+
|
273 |
+
if ($max_invoice_number == '') {
|
274 |
+
// First time! Use order number as starting point.
|
275 |
+
$order_number = ltrim($this->order->get_order_number(), '#');
|
276 |
+
$invoice_number = $order_number;
|
277 |
+
} else {
|
278 |
+
$invoice_number = $max_invoice_number+1;
|
279 |
+
}
|
280 |
+
|
281 |
+
$success = $wpdb->query( 'INSERT INTO ' . $wpdb->postmeta . ' (post_id,meta_key,meta_value) VALUES (' . $order_id . ',"_wcpdf_invoice_number", '.$invoice_number.')' );
|
282 |
+
}
|
283 |
+
// die($invoice_number);
|
284 |
+
}
|
285 |
+
|
286 |
+
return $invoice_number;
|
287 |
+
}
|
288 |
+
|
289 |
/**
|
290 |
* Return evaluated template contents
|
291 |
*/
|
329 |
// Set item quantity
|
330 |
$data['quantity'] = $item['qty'];
|
331 |
|
332 |
+
// Set the line total (=before discount)
|
333 |
+
$data['line_total'] = $this->wc_price( $item['line_total'] );
|
334 |
+
$data['line_tax'] = $this->wc_price( $item['line_tax'] );
|
335 |
$data['tax_rates'] = $this->get_tax_rate( $item['tax_class'], $item['line_total'], $item['line_tax'] );
|
336 |
|
337 |
+
// Set the line subtotal
|
338 |
+
$data['line_subtotal'] = $this->wc_price( $item['line_subtotal'] );
|
339 |
+
$data['line_subtotal_tax'] = $this->wc_price( $item['line_subtotal_tax'] );
|
340 |
$data['ex_price'] = $this->get_formatted_item_price ( $item, 'total', 'excl' );
|
341 |
$data['price'] = $this->get_formatted_item_price ( $item, 'total' );
|
342 |
|
411 |
if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) )
|
412 |
return;
|
413 |
|
414 |
+
if ( $tax_display == 'excl' ) {
|
415 |
+
$item_price = $this->wc_price( ($this->order->get_line_subtotal( $item )) / $divider );
|
416 |
+
} else {
|
417 |
+
$item_price = $this->wc_price( ($this->order->get_line_subtotal( $item, true )) / $divider );
|
418 |
+
}
|
419 |
+
|
420 |
+
return $item_price;
|
421 |
+
}
|
422 |
+
|
423 |
+
/**
|
424 |
+
* wrapper for wc2.1 depricated price function
|
425 |
+
*/
|
426 |
+
public function wc_price( $price, $args = array() ) {
|
427 |
if ( version_compare( WOOCOMMERCE_VERSION, '2.1' ) >= 0 ) {
|
428 |
// WC 2.1 or newer is used
|
429 |
+
$args['currency'] = $this->order->get_order_currency();
|
430 |
+
$formatted_price = wc_price( $price, $args );
|
|
|
|
|
|
|
431 |
} else {
|
432 |
+
$formatted_price = woocommerce_price( $price );
|
|
|
|
|
|
|
|
|
|
|
433 |
}
|
434 |
|
435 |
+
return $formatted_price;
|
|
|
436 |
}
|
437 |
+
|
438 |
/**
|
439 |
* Get the tax rates/percentages for a given tax class
|
440 |
* @param string $tax_class tax class slug
|
includes/class-wcpdf-settings.php
CHANGED
@@ -316,6 +316,39 @@ if ( ! class_exists( 'WooCommerce_PDF_Invoices_Settings' ) ) {
|
|
316 |
)
|
317 |
);
|
318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
// Section.
|
320 |
add_settings_section(
|
321 |
'extra_template_fields',
|
316 |
)
|
317 |
);
|
318 |
|
319 |
+
add_settings_field(
|
320 |
+
'display_number',
|
321 |
+
__( 'Number to display on invoice', 'wpo_wcpdf' ),
|
322 |
+
array( &$this, 'select_element_callback' ),
|
323 |
+
$option,
|
324 |
+
'template_settings',
|
325 |
+
array(
|
326 |
+
'menu' => $option,
|
327 |
+
'id' => 'display_number',
|
328 |
+
'options' => array(
|
329 |
+
'order_number' => __( 'WooCommerce order number' , 'wpo_wcpdf' ),
|
330 |
+
'invoice_number'=> __( 'Built-in sequential invoice number' , 'wpo_wcpdf' ),
|
331 |
+
),
|
332 |
+
'description' => __( 'If you are using the WooCommerce Sequential Order Numbers plugin, select the WooCommerce order number', 'wpo_wcpdf' ),
|
333 |
+
)
|
334 |
+
);
|
335 |
+
|
336 |
+
add_settings_field(
|
337 |
+
'display_date',
|
338 |
+
__( 'Date to display on invoice', 'wpo_wcpdf' ),
|
339 |
+
array( &$this, 'select_element_callback' ),
|
340 |
+
$option,
|
341 |
+
'template_settings',
|
342 |
+
array(
|
343 |
+
'menu' => $option,
|
344 |
+
'id' => 'display_date',
|
345 |
+
'options' => array(
|
346 |
+
'order_date' => __( 'Order date' , 'wpo_wcpdf' ),
|
347 |
+
'invoice_date' => __( 'Invoice date' , 'wpo_wcpdf' ),
|
348 |
+
),
|
349 |
+
)
|
350 |
+
);
|
351 |
+
|
352 |
// Section.
|
353 |
add_settings_section(
|
354 |
'extra_template_fields',
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: pomegranate
|
|
3 |
Tags: woocommerce, print, pdf, bulk, packing slips, invoices, delivery notes, invoice, packing slip, export, email
|
4 |
Requires at least: 3.5 and WooCommerce 2.0
|
5 |
Tested up to: 3.8 and WooCommerce 2.1
|
6 |
-
Stable tag: 1.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -17,6 +17,7 @@ This WooCommerce extension automatically adds a PDF invoice to the order confirm
|
|
17 |
* Export invoices or packing slips to PDF (individually or in bulk)
|
18 |
* Automatically attach invoice PDF to order confirmation email
|
19 |
* Users can download their invoices from the My Account page
|
|
|
20 |
* **Available in: Dutch, English, French, German, Hungarian, Italian & Spanish**
|
21 |
|
22 |
= Fully customizable =
|
@@ -71,6 +72,22 @@ This plugin is translation ready, which means that you can translate it using st
|
|
71 |
7. Enter the translations. invoice and packing-slip now have two translation fields, single & plural. Note that this is a filename, so replace spaces with a - just to be sure!
|
72 |
8. Save as `wpo_wcpdf-xx_XX.po`, where you replace xx_XX with your language code & country code suffix (da_DK, pl_PL, de_DE etc.)
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
= Fatal error: Allowed memory size of ######## bytes exhausted (tried to allocate ### bytes) =
|
75 |
|
76 |
This usually only happens on batch actions. PDF creation is a memory intensive job, especially if it includes several pages with images. Go to WooCommerce > System Status to check your WP Memory Limit. We recommend setting it to 128mb or more.
|
@@ -84,6 +101,10 @@ This usually only happens on batch actions. PDF creation is a memory intensive j
|
|
84 |
|
85 |
== Changelog ==
|
86 |
|
|
|
|
|
|
|
|
|
87 |
= 1.1.6 =
|
88 |
* Feature: Hungarian translations added - thanks Joseph!
|
89 |
* Tweak: Better debug code.
|
3 |
Tags: woocommerce, print, pdf, bulk, packing slips, invoices, delivery notes, invoice, packing slip, export, email
|
4 |
Requires at least: 3.5 and WooCommerce 2.0
|
5 |
Tested up to: 3.8 and WooCommerce 2.1
|
6 |
+
Stable tag: 1.2.0
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
17 |
* Export invoices or packing slips to PDF (individually or in bulk)
|
18 |
* Automatically attach invoice PDF to order confirmation email
|
19 |
* Users can download their invoices from the My Account page
|
20 |
+
* Sequential invoice numbers (fully customizable with filters, see the [FAQ](http://wordpress.org/plugins/woocommerce-pdf-invoices-packing-slips/faq/))
|
21 |
* **Available in: Dutch, English, French, German, Hungarian, Italian & Spanish**
|
22 |
|
23 |
= Fully customizable =
|
72 |
7. Enter the translations. invoice and packing-slip now have two translation fields, single & plural. Note that this is a filename, so replace spaces with a - just to be sure!
|
73 |
8. Save as `wpo_wcpdf-xx_XX.po`, where you replace xx_XX with your language code & country code suffix (da_DK, pl_PL, de_DE etc.)
|
74 |
|
75 |
+
= How to I add a prefix, suffix or offset to the invoice number? =
|
76 |
+
|
77 |
+
You can do this via a filter in your theme's `functions.php` (Some themes have a "custom functions" area in the settings).
|
78 |
+
|
79 |
+
`
|
80 |
+
add_filter( 'wpo_wcpdf_invoice_number', 'wpo_wcpdf_invoice_number', 10, 4 );
|
81 |
+
|
82 |
+
function wpo_wcpdf_invoice_number( $invoice_number, $order_number, $order_id, $order_date ) {
|
83 |
+
$prefix = 'ABC';
|
84 |
+
$order_year = date_i18n( 'Y', strtotime( $order_date ) );
|
85 |
+
$offset = 10000;
|
86 |
+
$invoice_number = $prefix . $order_year . ($offset + $invoice_number);
|
87 |
+
return $invoice_number;
|
88 |
+
}
|
89 |
+
`
|
90 |
+
|
91 |
= Fatal error: Allowed memory size of ######## bytes exhausted (tried to allocate ### bytes) =
|
92 |
|
93 |
This usually only happens on batch actions. PDF creation is a memory intensive job, especially if it includes several pages with images. Go to WooCommerce > System Status to check your WP Memory Limit. We recommend setting it to 128mb or more.
|
101 |
|
102 |
== Changelog ==
|
103 |
|
104 |
+
= 1.2.0 =
|
105 |
+
* Feature: Sequential invoice numbers (set upon invoice creation).
|
106 |
+
* Feature: Invoice date (set upon invoice creation).
|
107 |
+
|
108 |
= 1.1.6 =
|
109 |
* Feature: Hungarian translations added - thanks Joseph!
|
110 |
* Tweak: Better debug code.
|
woocommerce-pdf-invoices-packingslips.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: http://www.wpovernight.com
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
-
* Version: 1.
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
@@ -263,30 +263,74 @@ if ( !class_exists( 'WooCommerce_PDF_Invoices' ) ) {
|
|
263 |
echo $this->get_shipping_method();
|
264 |
}
|
265 |
|
266 |
-
|
267 |
/**
|
268 |
-
* Return/Show order number
|
269 |
*/
|
270 |
public function get_order_number() {
|
271 |
// Trim the hash to have a clean number but still
|
272 |
// support any filters that were applied before.
|
273 |
$order_number = ltrim($this->export->order->get_order_number(), '#');
|
274 |
-
return $order_number;
|
275 |
}
|
276 |
public function order_number() {
|
277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
278 |
}
|
279 |
-
|
280 |
/**
|
281 |
* Return/Show the order date
|
282 |
*/
|
283 |
public function get_order_date() {
|
284 |
-
|
|
|
285 |
}
|
286 |
public function order_date() {
|
287 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
}
|
289 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
/**
|
291 |
* Return the order items
|
292 |
*/
|
3 |
* Plugin Name: WooCommerce PDF Invoices & Packing Slips
|
4 |
* Plugin URI: http://www.wpovernight.com
|
5 |
* Description: Create, print & email PDF invoices & packing slips for WooCommerce orders.
|
6 |
+
* Version: 1.2.0
|
7 |
* Author: Ewout Fernhout
|
8 |
* Author URI: http://www.wpovernight.com
|
9 |
* License: GPLv2 or later
|
263 |
echo $this->get_shipping_method();
|
264 |
}
|
265 |
|
|
|
266 |
/**
|
267 |
+
* Return/Show order number (or invoice number)
|
268 |
*/
|
269 |
public function get_order_number() {
|
270 |
// Trim the hash to have a clean number but still
|
271 |
// support any filters that were applied before.
|
272 |
$order_number = ltrim($this->export->order->get_order_number(), '#');
|
273 |
+
return apply_filters( 'wpo_wcpdf_order_number', $order_number);
|
274 |
}
|
275 |
public function order_number() {
|
276 |
+
// Check for setting: not very semantical but helps a lot for backwards compatibiity!
|
277 |
+
$display_number = isset($this->settings->template_settings['display_number'])?$this->settings->template_settings['display_number']:'order_number';
|
278 |
+
if ( $display_number == 'invoice_number' ) {
|
279 |
+
echo $this->get_invoice_number();
|
280 |
+
} else {
|
281 |
+
echo $this->get_order_number();
|
282 |
+
}
|
283 |
}
|
284 |
+
|
285 |
/**
|
286 |
* Return/Show the order date
|
287 |
*/
|
288 |
public function get_order_date() {
|
289 |
+
$date = date_i18n( get_option( 'date_format' ), strtotime( $this->export->order->order_date ) );
|
290 |
+
return apply_filters( 'wpo_wcpdf_order_date', $date );
|
291 |
}
|
292 |
public function order_date() {
|
293 |
+
// Check for setting: not very semantical but helps a lot for backwards compatibiity!
|
294 |
+
$display_date = isset($this->settings->template_settings['display_date'])?$this->settings->template_settings['display_date']:'order_date';
|
295 |
+
|
296 |
+
if ( $display_date == 'order_date' ) {
|
297 |
+
echo $this->get_order_date();
|
298 |
+
} else {
|
299 |
+
echo $this->get_invoice_date();
|
300 |
+
}
|
301 |
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Return/Show invoice number
|
305 |
+
*/
|
306 |
+
public function get_invoice_number() {
|
307 |
+
$invoice_number = $this->export->get_invoice_number( $this->export->order->id );
|
308 |
+
return apply_filters( 'wpo_wcpdf_invoice_number', $invoice_number, $this->get_order_number(), $this->export->order->id, $this->get_order_date() );
|
309 |
+
}
|
310 |
+
public function invoice_number() {
|
311 |
+
echo $this->get_invoice_number();
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Return/Show the invoice date
|
316 |
+
*/
|
317 |
+
public function get_invoice_date() {
|
318 |
+
$invoice_date = get_post_meta($this->export->order->id,'_wcpdf_invoice_date',true);
|
319 |
+
|
320 |
+
// add invoice date if it doesn't exist
|
321 |
+
if ( empty($invoice_date) || !isset($invoice_date) ) {
|
322 |
+
$invoice_date = current_time('mysql');
|
323 |
+
update_post_meta( $this->export->order->id, '_wcpdf_invoice_date', $invoice_date );
|
324 |
+
}
|
325 |
+
|
326 |
+
$formatted_invoice_date = date_i18n( get_option( 'date_format' ), strtotime( $invoice_date ) );
|
327 |
+
|
328 |
+
return apply_filters( 'wpo_wcpdf_invoice_date', $formatted_invoice_date, $invoice_date );
|
329 |
+
}
|
330 |
+
public function invoice_date() {
|
331 |
+
echo $this->get_invoice_date();
|
332 |
+
}
|
333 |
+
|
334 |
/**
|
335 |
* Return the order items
|
336 |
*/
|