Support » Plugin: WooCommerce PDF Invoices & Packing Slips » Get Invoice number for order

  • Resolved Václav Greif

    (@vasikgreif)


    Hello, I’m trying to get invoice number for specific order.

    I tried to do:

    
    global $wpo_wcpdf;
    $wpo_wcpdf->export->get_invoice_date( $invoice->order_id )
    

    Which results in:

    [10-Jan-2018 17:08:01 UTC] PHP Fatal error:  Uncaught exception 'Exception' with message 'Call to undefined method WPO\WC\PDF_Invoices\Legacy\Legacy_Export::get_invoice_date()' in /var/www/vhosts/website.com/httpdocs/wp-content/plugins/woocommerce-pdf-invoices-packing-slips/includes/legacy/class-wcpdf-legacy-export.php:53
    Stack trace:
    #0 /var/www/vhosts/website.com/httpdocs/wp-content/plugins/woo-export-invoices/woo-export-invoices.php(95): WPO\WC\PDF_Invoices\Legacy\Legacy_Export->__call('get_invoice_dat...', Array)
    #1 /var/www/vhosts/website.com/httpdocs/wp-content/plugins/woo-export-invoices/woo-export-invoices.php(95): WPO\WC\PDF_Invoices\Legacy\Legacy_Export->get_invoice_date('4850')
    #2 [internal function]: Woo_Export_Orders\Init->download_csv('')
    #3 /var/www/vhosts/website.com/httpdocs/wp-includes/class-wp-hook.php(298): call_user_func_array(Array, Array)
    #4 /var/www/vhosts/website.com/httpdocs/wp-includes/class-wp-hook.php(323): WP_Hook->apply_filters('', Array)
    #5 /var/www/vhosts/website.com/httpdocs/wp-includes/plugin.php(453): WP_H in /var/www/vhosts/website.com/httpdocs/wp-content/plugins/woocommerce-pdf-invoices-packing-slips/includes/legacy/class-wcpdf-legacy-export.php on line 53

    Am I doing something wrong? Thanks

Viewing 15 replies - 1 through 15 (of 17 total)
  • Plugin Author Ewout

    (@pomegranate)

    Yes, $wpo_wcpdf is deprecated and shouldn’t be used anywhere.
    Assuming the invoice object is loaded as you write in the above, you can simply do:

    
    $invoice_number = $invoice->get_number();
    $invoice_date = $invoice->get_date();
    

    Both of these are objects, but they will also work as a string if you just echo them (using the __toString magic method).
    If you want to control the formatting:

    
    $invoice_number = $invoice->get_number();
    $formatted_invoice_number = $invoice_number->get_formatted();
    $plain_invoice_number = $invoice_number->get_plain();
    $invoice_date = $invoice->get_date();
    $formatted_invoice_date = $invoice_date->date_i18n( 'Y-m-d' );
    

    If $invoice in your code wasn’t the actual pdf invoice object, you can get it from an order_id:

    
    $invoice = wcpdf_get_invoice( $order_id );
    

    Hope that helps!

    Ewout

    • This reply was modified 1 year, 10 months ago by Ewout. Reason: code typo

    Thanks for reply! What I’m trying to do is build the array of invoices issued between specific dates. Here’s my code:

                // Get the invoices
                $invoices = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}wcpdf_invoice_number WHERE DATE(date) >= '{$date_from}' AND  DATE(date) <= '{$date_to}'");
    
                // If there are no invoices matching the criteria, just die
                if (empty($invoices))
                    wp_die('No invoices matched the date selection');
    
                $export_invoices = [];
    
                foreach ($invoices as $invoice) {
                    if ($invoice->order_id) {
                        $order = wc_get_order($invoice->order_id);
                        $document = wcpdf_get_invoice($order);
    
                        $export_invoices[] = [
                            'invoice_no' => $document->get_number(),
                            'invoice_date' => $document->get_date(),
                            'total' => $order->get_total(),
                        ];
                    }
    
                }

    That results in Fatal error [10-Jan-2018 19:36:43 UTC] PHP Fatal error: Class 'WPO\WC\PDF_Invoices\Documents\Order_Document_Methods' not found in /var/www/vhosts/mywebsite.com/httpdocs/wp-content/plugins/woocommerce-pdf-invoices-packing-slips/includes/legacy/class-wcpdf-legacy-document.php on line 23

    I’m obviously missing something here..Any help?

    Thanks

    Plugin Author Ewout

    (@pomegranate)

    Looks like this is executed too early. At what hook is this running?
    Also, it looks like there may still be $wpo_wcpdf references in either your template or other parts of the code, as otherwise the legacy class would not be loaded.

    Just FYI, the {$wpdb->prefix}wcpdf_invoice_number table is just an engine to generate the invoice number, but as soon as the ‘next invoice number’ is entered, it gets cleared. It may therefor not be a reliable reference for invoices from your site – you’d have to query the WC orders directly for that.

    Hello, thanks a lot for your help!

    This code is executed on init action. I’m not aware of any references to the $wpo_wcpdf object (at least i my code), here’s the complete code, not much going on there.

    For getting the invoices, I need to get invoices between specific dates, not orders. I mean, the invoice can be issued two weeks after the order is placed. Is there any way to get the invoices between specific dates, without querying all the orders and comparing against invoice date?

    Plugin Author Ewout

    (@pomegranate)

    try admin_init or otherwise init with prio 9999.
    Check your invoice template files for $wpo_wcpdf references and make sure to turn off legacy mode in the Status tab.

    Changing to admin_init worked!

    Last bit of puzzle – any way to query the orders to get orders with invoices between specific dates? Is the invoice date saved as postmeta somehow?

    Thanks!

    Plugin Author Ewout

    (@pomegranate)

    yes, _wcpdf_invoice_date, which is a UTC (!) timestamp. Technically this is still postmeta, although WooCommerce has deprecated it and recommends using the order getters. If you want to do this correctly you can use wc_get_orders() with a custom parameter.

    Plugin Author Ewout

    (@pomegranate)

    Untested, but this may work:

    
    function wpo_wcpdf_invoice_date_query_var( $wp_query_args, $query_vars, $order_store_cpt ) {
    	if ( isset( $query_vars[ 'invoice_date' ] ) && '' !== $query_vars[ 'invoice_date' ] ) {
    		$wp_query_args = $order_store_cpt->parse_date_for_wp_query( $query_vars[ 'invoice_date' ], '_wcpdf_invoice_date', $wp_query_args );
    	}
    
    	return $wp_query_args;
    }
    add_filter( 'woocommerce_order_data_store_cpt_get_orders_query', 'wpo_wcpdf_invoice_date_query_var', 10, 3 );
    

    For which you could then use the same syntax as other date queries.

    • This reply was modified 1 year, 10 months ago by Ewout. Reason: query syntax

    Thanks!

    What I ended up with is:

    
                // Get the invoices
                $args = [
                    'post_type' => 'shop_order',
                    'post_status' => 'any',
                    'posts_per_page' => -1,
                    'meta_query' => array(
                        'relation' => 'AND',
                        'date_from' => array(
                            'key' => '_wcpdf_invoice_date_formatted',
                            'value' => date('Y-m-d H:i:s',strtotime($date_from)),
                            'compare' => '>='
                        ),
                        'date_to' => array(
                            'key' => '_wcpdf_invoice_date_formatted',
                            'value' => date('Y-m-d H:i:s',strtotime($date_to . ' + 1 day')),
                            'compare' => '<='
                        ),
                    ),
                ];
    
                $the_query = new \WP_Query( $args );
    
    Plugin Author Ewout

    (@pomegranate)

    I just tested my own code and it works as expected. I would recommend using that instead of a WP Query for better future compatibility.

    With that filter in place, you can simply do:

    
    $orders = wc_get_orders( array( 'invoice_date' => '2017-12-01...2017-12-31' ) );
    

    Date queries use a standard format:
    YYYY-MM-DD – Matches on orders during that one day in site timezone.

    >YYYY-MM-DD – Matches on orders after that one day in site timezone.

    >=YYYY-MM-DD – Matches on orders during or after that one day in site timezone.

    <YYYY-MM-DD – Matches on orders before that one day in site timezone.

    <=YYYY-MM-DD – Matches on orders during or before that one day in site timezone.

    YYYY-MM-DD...YYYY-MM-DD – Matches on orders during or in between the days in site timezone.

    TIMESTAMP
    – Matches on orders during that one second in UTC timezone.

    >TIMESTAMP – Matches on orders after that one second in UTC timezone.

    >=TIMESTAMP – Matches on orders during or after that one second in UTC timezone.

    <TIMESTAMP – Matches on orders before that one second in UTC timezone.

    <=TIMESTAMP – Matches on orders during or before that one second in UTC timezone.

    TIMESTAMP...TIMESTAMP – Matches on orders during or in between the seconds in UTC timezone.

    Hello,
    thanks, this works great. Thank you for an INCREDIBLE support!

    V.

    Plugin Author Ewout

    (@pomegranate)

    You’re welcome 🙂
    If you can spare a minute of your time, I’d appreciate a review: https://wordpress.org/support/plugin/woocommerce-pdf-invoices-packing-slips/reviews/

    Thanks in advance!
    Ewout

    Hello,
    I have one more issue here: the _wcpdf_invoice_date field is now UTC timestamp, but it used to be YYYY-mm-dd H:i:s format in previous versions of WCPDF. When I use the code, I get only orders older than 21.9.2017, because older orders have the _wcpdf_invoice_date stored in the older format.

    Any fix for this?
    Thanks!

    Plugin Author Ewout

    (@pomegranate)

    With what method exactly? I would expect it to be the other way around (assuming you’re using the wc_get_orders method), which is also how it behaved in my tests. I believe the $order_store_cpt->parse_date_for_wp_query() method assumes it’s stored as timestamp in the DB.

    Regardless, for backwards compatibility I think you’d have to convert the old format to timestamps. I may actually create a DB upgrade routine that will fix this discrepancy for legacy data…

    Hello, exactly, when I use the wc_get_orders, I get only the new orders with meta saved as timestamp.

    What’s the proper PHP function to convert old dates to UTC timestamps? Should it be something like strtotime(gmdate("M d Y H:i:s",strtotime('2018-01-01 10:20:22'))) ?

    Thanks

Viewing 15 replies - 1 through 15 (of 17 total)
  • The topic ‘Get Invoice number for order’ is closed to new replies.