diff --git a/lang/wc-invoice-pdf-de_DE.mo b/lang/wc-invoice-pdf-de_DE.mo index b00b464..7909df1 100644 Binary files a/lang/wc-invoice-pdf-de_DE.mo and b/lang/wc-invoice-pdf-de_DE.mo differ diff --git a/lang/wc-invoice-pdf-de_DE.po b/lang/wc-invoice-pdf-de_DE.po index d29637d..154aa77 100644 --- a/lang/wc-invoice-pdf-de_DE.po +++ b/lang/wc-invoice-pdf-de_DE.po @@ -270,8 +270,23 @@ msgstr "Einstellungen gespeichert" msgid "To the minute calculation" msgstr "Minuten-genaue Berechnung" -msgid "Working hours" -msgstr "Arbeitszeiten" +msgid "Services" +msgstr "Dienstleistungen" + +msgid "Unit information" +msgstr "Angaben zur Einheit" + +msgid "Unit" +msgstr "Einheit" + +msgid "Unit (plural)" +msgstr "Einheit (plural)" + +msgid "The unit next to the quantity (default: h)" +msgstr "Die Einhait nach Angabe der Menge (Standardwert: h)" + +msgid "The unit when quantity is more than one (optional)" +msgstr "Die Einheit wenn die Menge größer als eins (optional)" msgid "Webspace" msgstr "Webspeicher" diff --git a/model/invoice-list.php b/model/invoice-list.php index 62bab18..b5b9c3d 100644 --- a/model/invoice-list.php +++ b/model/invoice-list.php @@ -243,6 +243,8 @@ public function prepare_items() case 'paid': $invoice->Paid(); $invoice->Save(); + // update WC_Order status to completed when marked as paid + $invoice->order->update_status('completed'); break; case 'cancel': $invoice->Cancel(); diff --git a/model/invoice-pdf.php b/model/invoice-pdf.php index c906929..87c854c 100644 --- a/model/invoice-pdf.php +++ b/model/invoice-pdf.php @@ -25,9 +25,10 @@ public function BuildInvoice($invoice, $isOffer = false, $stream = false) $isB2C = true; } - $formatStyle = \NumberFormatter::DECIMAL; + $formatStyle = \NumberFormatter::CURRENCY; $formatter = new \NumberFormatter(get_locale(), $formatStyle); - $formatter->setPattern("#0.00 " . $order->get_currency()); + $formatter->setSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL, $order->get_currency()); + $formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $order->get_currency()); $items = $order->get_items(); @@ -71,7 +72,6 @@ public function BuildInvoice($invoice, $isOffer = false, $stream = false) $pdf->addObject($all, 'all'); - $pdf->ezSetDy(-60); $y = $pdf->y; @@ -104,8 +104,8 @@ public function BuildInvoice($invoice, $isOffer = false, $stream = false) $colOptions = [ 'num' => ['width' => 30], 'desc' => [], - 'qty' => ['justification' => 'right', 'width' => 62], - 'price' => ['justification' => 'right', 'width' => 70], + 'qty' => ['justification' => 'right', 'width' => 55], + 'price' => ['justification' => 'right', 'width' => 80], 'total' => ['justification' => 'right', 'width' => 80], ]; @@ -144,10 +144,10 @@ public function BuildInvoice($invoice, $isOffer = false, $stream = false) } $qtyStr = number_format($v['qty'], 0, ',', ' ') . ' ' . $product->get_price_suffix('', $v['qty']); $product_name .= "\n" . __('Period', 'wc-invoice-pdf') . ": " . \strftime('%x', $current->getTimestamp()) ." - ". \strftime('%x', $next->getTimestamp()) . ''; - } elseif ($product instanceof \WC_Product_Hour) { + } elseif ($product instanceof \WC_Product_Service) { // check if product type is "hour" to output hours instead of Qty $qtyStr = number_format($v['qty'], 1, ',', ' '); - $qtyStr.= '' . $product->get_price_suffix('', $v['qty'], true); + $qtyStr.= '' . $product->get_price_suffix('', $v['qty']); } else { $qtyStr = number_format($v['qty'], 2, ',', ' '); } diff --git a/readme.txt b/readme.txt index 2414f2b..6f00558 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: ole1986 Tags: woocommerce, WC, invoicing, billing, recurring, order, pdf, automation, read-only, law Donate link: https://www.paypal.com/cgi-bin/webscr?item_name=Donation+WC+Recurring+Invoice+Pdf&cmd=_donations&business=ole.k@web.de Requires at least: 3.1 -Tested up to: 6.4 +Tested up to: 6.5 Stable tag: trunk License: GPLv2 License URI: http://www.gnu.org/licenses/gpl-2.0.html diff --git a/wc-invoice-pdf.php b/wc-invoice-pdf.php index 9be6677..2e5c45b 100644 --- a/wc-invoice-pdf.php +++ b/wc-invoice-pdf.php @@ -2,14 +2,14 @@ /* * Plugin Name: WC Recurring Invoice PDF * Description: WooCommerce invoice pdf plugin with recurring payments (scheduled) - * Version: 1.5.20 - * Author: ole1986 + * Version: 1.5.21 + * Author: ole1986 * Author URI: https://github.com/ole1986/wc-invoice-pdf * Plugin URI: https://github.com/ole1986/wc-invoice-pdf/releases * Text Domain: wc-invoice-pdf * * WC requires at least: 3.0.0 - * WC tested up to: 8.5 + * WC tested up to: 8.9 */ namespace WCInvoicePdf; @@ -273,68 +273,20 @@ public static function migrate() if (!get_transient('wc-invoice-pdf-migrate')) { return; } + + // increase when something to migration + $migrationIncrement = 4; + $plugin = get_plugin_data(__FILE__); // migration - $version = get_option('_ispconfig_invoice_version', 0); - - if ($version > 0 && $version <= 2) { - // MIGRATION FROM VERSIONS LOWER 1.5.0 - - // fetch all orders containing a "Domain" meta data - $post_ids = $wpdb->get_col("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'Domain'"); - // get all products with product type webspace - $webspace_ids = wc_get_products(['limit' => -1, 'type' => 'webspace', 'return' => 'ids']); - - // go through all matching orders with Domain meta data - foreach ($post_ids as $order_id) { - $order = wc_get_order($order_id); - $items = $order->get_items('line_item'); - - // fetch the first webspace product (asuming ithas only one) - $webspace_product = array_pop(array_filter($items, function ($item) { - return get_class($item) === 'WC_Order_Item_Product'; - })); - - if (!$webspace_product) { - // skip when no webspace product found - continue; - } - - $domain = $order->get_meta('Domain', true); - $metadata = $webspace_product->get_meta_data(); - - if (!empty($metadata)) { - usort($metadata, function ($a, $b) { - return $a->id <= $b->id ? -1 : 1; - }); - - $newmetadata = []; - // remove all meta data - foreach ($metadata as $meta) { - $newmetadata[] = ["id" => 0, "key" => $meta->key, "value" => $meta->value]; - $webspace_product->delete_meta_data($meta->key); - } - - // put the domain meta at first - array_unshift($newmetadata, ["id" => 0, "key" => "Domain", "value" => $domain]); - - $webspace_product->set_meta_data($newmetadata); - } else { - $webspace_product->add_meta_data('Domain', $domain); - } - - $webspace_product->save_meta_data(); - - $order->delete_meta_data('Domain'); - $order->save_meta_data(); - } - - $plugin = get_plugin_data(__FILE__); + $version = intval(get_option('wc-invoice-pdf-version', $migrationIncrement)); + + if ($version < $migrationIncrement) { + $wpdb->query("UPDATE $wpdb->terms SET name = 'service', slug = 'service' WHERE term_id IN (SELECT t.term_id FROM $wpdb->terms t LEFT JOIN $wpdb->term_taxonomy tt ON (t.term_id = tt.term_id) WHERE name = 'hour')"); + $wpdb->query("UPDATE $wpdb->postmeta SET meta_key = '_qty_suffix', meta_value = 'min' WHERE meta_id IN (SELECT meta_id FROM $wpdb->postmeta pm LEFT JOIN $wpdb->posts p ON p.ID = pm.post_id WHERE p.post_type = 'product' AND pm.meta_key = '_hour_useminute' AND pm.meta_value = 'yes')"); - delete_option('_ispconfig_invoice_version'); - update_option('wc-invoice-pdf-version', 3); - - echo '' . $plugin['Name'] .': Successfully migrated products from ' . count($post_ids) .' orders'; + update_option('wc-invoice-pdf-version', $migrationIncrement); + echo '' . $plugin['Name'] .': Successfully migrated service product_type'; } delete_transient('wc-invoice-pdf-migrate'); diff --git a/wc/wc_product_service.php b/wc/wc_product_service.php index ae71d0d..464e795 100644 --- a/wc/wc_product_service.php +++ b/wc/wc_product_service.php @@ -4,28 +4,33 @@ return; } -add_filter('woocommerce_product_data_tabs', ['WC_Product_Hour','hour_product_data_tab']); +add_filter('woocommerce_product_data_tabs', ['WC_Product_Service','hour_product_data_tab']); -add_action('woocommerce_product_data_panels', ['WC_Product_Hour','product_data_fields']); -add_action('woocommerce_process_product_meta_hour', ['WC_Product_Hour', 'metadata_save']); +add_action('woocommerce_product_data_panels', ['WC_Product_Service','product_data_fields']); +add_action('woocommerce_process_product_meta_service', ['WC_Product_Service', 'metadata_save']); -add_action('admin_footer', ['WC_Product_Hour', 'jsRegister']); -add_filter('product_type_selector', ['WC_Product_Hour','register']); +add_action('admin_footer', ['WC_Product_Service', 'jsRegister']); +add_filter('product_type_selector', ['WC_Product_Service','register']); -class WC_Product_Hour extends WC_Product +class WC_Product_Service extends WC_Product { public static $current; public function __construct($product) { - $this->product_type = 'hour'; + $this->product_type = 'service'; parent::__construct($product); } + public function get_type() + { + return 'service'; + } + public static function register($types) { // Key should be exactly the same as in the class product_type parameter - $types[ 'hour' ] = __('Working hours', 'wc-invoice-pdf'); + $types[ 'service' ] = __('Services', 'wc-invoice-pdf'); return $types; } @@ -35,7 +40,7 @@ public static function jsRegister() ?>
' . $plugin['Name'] .': Successfully migrated products from ' . count($post_ids) .' orders
' . $plugin['Name'] .': Successfully migrated service product_type