Merge pull request #17705 from woocommerce/feature/11259

Product backorder stock status
This commit is contained in:
Mike Jolley 2017-12-04 14:17:32 +00:00 committed by GitHub
commit baccd85793
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 615 additions and 234 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -2493,18 +2493,26 @@ table.wp-list-table {
}
}
mark.instock {
font-weight: 700;
color: $green;
background: transparent none;
line-height: 1;
}
mark {
&.instock,
&.outofstock,
&.onbackorder {
font-weight: 700;
background: transparent none;
line-height: 1;
}
mark.outofstock {
font-weight: 700;
color: #aa4444;
background: transparent none;
line-height: 1;
&.instock {
color: $green;
}
&.outofstock {
color: #aa4444;
}
&.onbackorder {
color: #eaa600;
}
}
.order-notes_head,

View File

@ -232,8 +232,12 @@ jQuery( function( $ ) {
$( 'input#_manage_stock' ).change( function() {
if ( $( this ).is( ':checked' ) ) {
$( 'div.stock_fields' ).show();
$( 'p.stock_status_field' ).hide();
} else {
var product_type = $( 'select#product-type' ).val();
$( 'div.stock_fields' ).hide();
$( 'p.stock_status_field:not( .hide_if_' + product_type + ' )' ).show();
}
}).change();

File diff suppressed because one or more lines are too long

View File

@ -60,10 +60,12 @@ jQuery(function( $ ) {
}
if ( 'yes' === manage_stock ) {
$( '.stock_qty_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_status_field' ).hide();
$( 'input[name="_manage_stock"]', '.inline-edit-row' ).attr( 'checked', 'checked' );
} else {
$( '.stock_qty_field', '.inline-edit-row' ).hide();
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide();
$( '.stock_status_field' ).show().removeAttr( 'style' );
$( 'input[name="_manage_stock"]', '.inline-edit-row' ).removeAttr( 'checked' );
}
@ -96,9 +98,11 @@ jQuery(function( $ ) {
$( '#the-list' ).on( 'change', '.inline-edit-row input[name="_manage_stock"]', function() {
if ( $( this ).is( ':checked' ) ) {
$( '.stock_qty_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_status_field' ).hide();
} else {
$( '.stock_qty_field', '.inline-edit-row' ).hide();
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide();
$( '.stock_status_field' ).show().removeAttr( 'style' );
}
});

View File

@ -1 +1 @@
jQuery(function(e){e("#the-list").on("click",".editinline",function(){inlineEditPost.revert();var t=e(this).closest("tr").attr("id");t=t.replace("post-","");var i=e("#woocommerce_inline_"+t),n=i.find(".sku").text(),o=i.find(".regular_price").text(),l=i.find(".sale_price ").text(),d=i.find(".weight").text(),s=i.find(".length").text(),c=i.find(".width").text(),a=i.find(".height").text(),r=i.find(".shipping_class").text(),_=i.find(".visibility").text(),m=i.find(".stock_status").text(),p=i.find(".stock").text(),u=i.find(".featured").text(),w=i.find(".manage_stock").text(),h=i.find(".menu_order").text(),f=i.find(".tax_status").text(),v=i.find(".tax_class").text(),k=i.find(".backorders").text(),x=o.replace(".",woocommerce_admin.mon_decimal_point),g=l.replace(".",woocommerce_admin.mon_decimal_point);e('input[name="_sku"]',".inline-edit-row").val(n),e('input[name="_regular_price"]',".inline-edit-row").val(x),e('input[name="_sale_price"]',".inline-edit-row").val(g),e('input[name="_weight"]',".inline-edit-row").val(d),e('input[name="_length"]',".inline-edit-row").val(s),e('input[name="_width"]',".inline-edit-row").val(c),e('input[name="_height"]',".inline-edit-row").val(a),e('select[name="_shipping_class"] option:selected',".inline-edit-row").attr("selected",!1).change(),e('select[name="_shipping_class"] option[value="'+r+'"]').attr("selected","selected").change(),e('input[name="_stock"]',".inline-edit-row").val(p),e('input[name="menu_order"]',".inline-edit-row").val(h),e('select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option').removeAttr("selected"),e('select[name="_tax_status"] option[value="'+f+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_tax_class"] option[value="'+v+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_visibility"] option[value="'+_+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_stock_status"] option[value="'+m+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_backorders"] option[value="'+k+'"]',".inline-edit-row").attr("selected","selected"),"yes"===u?e('input[name="_featured"]',".inline-edit-row").attr("checked","checked"):e('input[name="_featured"]',".inline-edit-row").removeAttr("checked"),"yes"===w?(e(".stock_qty_field",".inline-edit-row").show().removeAttr("style"),e('input[name="_manage_stock"]',".inline-edit-row").attr("checked","checked")):(e(".stock_qty_field",".inline-edit-row").hide(),e('input[name="_manage_stock"]',".inline-edit-row").removeAttr("checked"));var y=i.find(".product_type").text(),b=i.find(".product_is_virtual").text();"simple"===y||"external"===y?e(".price_fields",".inline-edit-row").show().removeAttr("style"):e(".price_fields",".inline-edit-row").hide(),"yes"===b?e(".dimension_fields",".inline-edit-row").hide():e(".dimension_fields",".inline-edit-row").show().removeAttr("style"),"grouped"===y?e(".stock_fields",".inline-edit-row").hide():e(".stock_fields",".inline-edit-row").show().removeAttr("style"),e('input[name="comment_status"]').parent().find(".checkbox-title").text(woocommerce_quick_edit.strings.allow_reviews)}),e("#the-list").on("change",'.inline-edit-row input[name="_manage_stock"]',function(){e(this).is(":checked")?e(".stock_qty_field",".inline-edit-row").show().removeAttr("style"):e(".stock_qty_field",".inline-edit-row").hide()}),e("#wpbody").on("click","#doaction, #doaction2",function(){e("input.text",".inline-edit-row").val(""),e("#woocommerce-fields").find("select").prop("selectedIndex",0),e("#woocommerce-fields-bulk").find(".inline-edit-group .change-input").hide()}),e("#wpbody").on("change","#woocommerce-fields-bulk .inline-edit-group .change_to",function(){0<e(this).val()?e(this).closest("div").find(".change-input").show():e(this).closest("div").find(".change-input").hide()}),e("#wpbody").on("click",".trash-product",function(){return window.confirm(woocommerce_admin.i18_delete_product_notice)})});
jQuery(function(e){e("#the-list").on("click",".editinline",function(){inlineEditPost.revert();var t=e(this).closest("tr").attr("id");t=t.replace("post-","");var i=e("#woocommerce_inline_"+t),n=i.find(".sku").text(),o=i.find(".regular_price").text(),d=i.find(".sale_price ").text(),l=i.find(".weight").text(),s=i.find(".length").text(),c=i.find(".width").text(),r=i.find(".height").text(),a=i.find(".shipping_class").text(),_=i.find(".visibility").text(),m=i.find(".stock_status").text(),p=i.find(".stock").text(),u=i.find(".featured").text(),w=i.find(".manage_stock").text(),f=i.find(".menu_order").text(),h=i.find(".tax_status").text(),k=i.find(".tax_class").text(),v=i.find(".backorders").text(),x=o.replace(".",woocommerce_admin.mon_decimal_point),g=d.replace(".",woocommerce_admin.mon_decimal_point);e('input[name="_sku"]',".inline-edit-row").val(n),e('input[name="_regular_price"]',".inline-edit-row").val(x),e('input[name="_sale_price"]',".inline-edit-row").val(g),e('input[name="_weight"]',".inline-edit-row").val(l),e('input[name="_length"]',".inline-edit-row").val(s),e('input[name="_width"]',".inline-edit-row").val(c),e('input[name="_height"]',".inline-edit-row").val(r),e('select[name="_shipping_class"] option:selected',".inline-edit-row").attr("selected",!1).change(),e('select[name="_shipping_class"] option[value="'+a+'"]').attr("selected","selected").change(),e('input[name="_stock"]',".inline-edit-row").val(p),e('input[name="menu_order"]',".inline-edit-row").val(f),e('select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option').removeAttr("selected"),e('select[name="_tax_status"] option[value="'+h+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_tax_class"] option[value="'+k+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_visibility"] option[value="'+_+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_stock_status"] option[value="'+m+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_backorders"] option[value="'+v+'"]',".inline-edit-row").attr("selected","selected"),"yes"===u?e('input[name="_featured"]',".inline-edit-row").attr("checked","checked"):e('input[name="_featured"]',".inline-edit-row").removeAttr("checked"),"yes"===w?(e(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),e(".stock_status_field").hide(),e('input[name="_manage_stock"]',".inline-edit-row").attr("checked","checked")):(e(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),e(".stock_status_field").show().removeAttr("style"),e('input[name="_manage_stock"]',".inline-edit-row").removeAttr("checked"));var y=i.find(".product_type").text(),b=i.find(".product_is_virtual").text();"simple"===y||"external"===y?e(".price_fields",".inline-edit-row").show().removeAttr("style"):e(".price_fields",".inline-edit-row").hide(),"yes"===b?e(".dimension_fields",".inline-edit-row").hide():e(".dimension_fields",".inline-edit-row").show().removeAttr("style"),"grouped"===y?e(".stock_fields",".inline-edit-row").hide():e(".stock_fields",".inline-edit-row").show().removeAttr("style"),e('input[name="comment_status"]').parent().find(".checkbox-title").text(woocommerce_quick_edit.strings.allow_reviews)}),e("#the-list").on("change",'.inline-edit-row input[name="_manage_stock"]',function(){e(this).is(":checked")?(e(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),e(".stock_status_field").hide()):(e(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),e(".stock_status_field").show().removeAttr("style"))}),e("#wpbody").on("click","#doaction, #doaction2",function(){e("input.text",".inline-edit-row").val(""),e("#woocommerce-fields").find("select").prop("selectedIndex",0),e("#woocommerce-fields-bulk").find(".inline-edit-group .change-input").hide()}),e("#wpbody").on("change","#woocommerce-fields-bulk .inline-edit-group .change_to",function(){0<e(this).val()?e(this).closest("div").find(".change-input").show():e(this).closest("div").find(".change-input").hide()}),e("#wpbody").on("click",".trash-product",function(){return window.confirm(woocommerce_admin.i18_delete_product_notice)})});

View File

@ -181,8 +181,6 @@ jQuery( function( $ ) {
/**
* Handles when a shipping method is selected.
*
* @param {Object} evt The JQuery event.
*/
shipping_method_selected: function() {
var shipping_methods = {};

View File

@ -4,7 +4,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WooCommerce 3.3-dev\n"
"Report-Msgid-Bugs-To: https://github.com/woocommerce/woocommerce/issues\n"
"POT-Creation-Date: 2017-12-04 13:45:22+00:00\n"
"POT-Creation-Date: 2017-12-04 14:13:56+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -5725,42 +5725,42 @@ msgstr ""
msgid "Invalid product tax status."
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1189
#: includes/abstracts/abstract-wc-product.php:1195
msgid ""
"The downloadable file %1$s cannot be used as it does not have an allowed "
"file type. Allowed types include: %2$s"
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1197
#: includes/abstracts/abstract-wc-product.php:1203
msgid "The downloadable file %s cannot be used as it does not exist on the server."
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1753
#: includes/abstracts/abstract-wc-product.php:1768
#: includes/class-wc-product-simple.php:54
msgid "Add to cart"
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1762
#: includes/abstracts/abstract-wc-product.php:1777
#: includes/class-wc-embed.php:112 includes/class-wc-product-simple.php:54
#: includes/class-wc-product-variable.php:60
msgid "Read more"
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1773
#: includes/abstracts/abstract-wc-product.php:1788
#: includes/class-wc-product-simple.php:67
#. translators: %s: Product title
msgid "Read more about &ldquo;%s&rdquo;"
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1927
#: includes/abstracts/abstract-wc-product.php:1942
#: includes/admin/class-wc-admin-reports.php:108
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:276
#: includes/admin/reports/class-wc-report-stock.php:114
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:278
#: includes/admin/reports/class-wc-report-stock.php:116
#: includes/wc-product-functions.php:801
msgid "Out of stock"
msgstr ""
#: includes/abstracts/abstract-wc-product.php:1929 templates/cart/cart.php:89
#: includes/abstracts/abstract-wc-product.php:1944 templates/cart/cart.php:89
msgid "Available on backorder"
msgstr ""
@ -6802,7 +6802,7 @@ msgstr ""
#: includes/admin/meta-boxes/class-wc-meta-box-order-data.php:285
#: includes/admin/meta-boxes/class-wc-meta-box-order-data.php:381
#: includes/admin/reports/class-wc-report-customer-list.php:157
#: includes/admin/reports/class-wc-report-stock.php:131
#: includes/admin/reports/class-wc-report-stock.php:133
#: includes/admin/settings/views/html-admin-page-shipping-classes.php:54
#: includes/admin/settings/views/html-admin-page-shipping-zone-methods.php:113
#: includes/admin/settings/views/html-admin-page-shipping-zones.php:78
@ -7317,7 +7317,7 @@ msgstr ""
#: includes/admin/class-wc-admin-menus.php:80
#: includes/admin/settings/class-wc-settings-api.php:42
#: includes/admin/views/html-admin-page-status-report.php:493
#: includes/class-wc-install.php:941
#: includes/class-wc-install.php:942
msgid "Settings"
msgstr ""
@ -7506,7 +7506,7 @@ msgid ""
msgstr ""
#: includes/admin/class-wc-admin-pointers.php:124
#: includes/admin/meta-boxes/views/html-product-data-variations.php:76
#: includes/admin/meta-boxes/views/html-product-data-variations.php:77
#: includes/admin/settings/class-wc-settings-products.php:44
#: includes/admin/settings/class-wc-settings-products.php:357
msgid "Downloadable products"
@ -7841,7 +7841,7 @@ msgstr ""
#: includes/admin/meta-boxes/views/html-order-items.php:233
#: includes/admin/meta-boxes/views/html-order-items.php:279
#: includes/admin/meta-boxes/views/html-product-data-general.php:52
#: includes/admin/meta-boxes/views/html-product-data-variations.php:117
#: includes/admin/meta-boxes/views/html-product-data-variations.php:118
#: includes/admin/plugin-updates/views/html-notice-untested-extensions-modal.php:44
#: includes/wc-account-functions.php:267
msgid "Cancel"
@ -8159,7 +8159,7 @@ msgstr ""
#: includes/admin/class-wc-admin-setup-wizard.php:773
#: includes/admin/meta-boxes/class-wc-meta-box-product-data.php:92
#: includes/admin/meta-boxes/views/html-order-shipping.php:17
#: includes/admin/meta-boxes/views/html-product-data-variations.php:70
#: includes/admin/meta-boxes/views/html-product-data-variations.php:71
#: includes/admin/settings/class-wc-settings-shipping.php:27
#: includes/admin/settings/class-wc-settings-tax.php:190
#: includes/admin/settings/views/html-settings-tax.php:32
@ -9394,7 +9394,7 @@ msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:430
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:560
#: includes/admin/views/html-bulk-edit-product.php:218
#: includes/admin/views/html-quick-edit-product.php:162
#: includes/admin/views/html-quick-edit-product.php:172
#: includes/export/class-wc-product-csv-exporter.php:93
msgid "In stock?"
msgstr ""
@ -9510,7 +9510,7 @@ msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:446
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:597
#: includes/admin/meta-boxes/views/html-product-data-general.php:103
#: includes/admin/meta-boxes/views/html-product-data-variations.php:77
#: includes/admin/meta-boxes/views/html-product-data-variations.php:78
#: includes/admin/meta-boxes/views/html-variation-admin.php:365
#: includes/export/class-wc-product-csv-exporter.php:109
msgid "Download limit"
@ -9524,7 +9524,7 @@ msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:448
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:581
#: includes/admin/reports/class-wc-report-stock.php:169
#: includes/admin/reports/class-wc-report-stock.php:171
#: includes/export/class-wc-product-csv-exporter.php:111
msgid "Parent"
msgstr ""
@ -9570,42 +9570,42 @@ msgid "Position"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:459
#: includes/export/class-wc-product-csv-exporter.php:468
#: includes/export/class-wc-product-csv-exporter.php:473
msgid "Attribute %d name"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:460
#: includes/export/class-wc-product-csv-exporter.php:469
#: includes/export/class-wc-product-csv-exporter.php:474
msgid "Attribute %d value(s)"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:461
#: includes/export/class-wc-product-csv-exporter.php:470
#: includes/export/class-wc-product-csv-exporter.php:475
msgid "Attribute %d visible"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:462
#: includes/export/class-wc-product-csv-exporter.php:471
#: includes/export/class-wc-product-csv-exporter.php:476
msgid "Attribute %d global"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:463
#: includes/export/class-wc-product-csv-exporter.php:508
#: includes/export/class-wc-product-csv-exporter.php:513
msgid "Attribute %d default"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:464
#: includes/export/class-wc-product-csv-exporter.php:443
#: includes/export/class-wc-product-csv-exporter.php:448
msgid "Download %d name"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:465
#: includes/export/class-wc-product-csv-exporter.php:444
#: includes/export/class-wc-product-csv-exporter.php:449
msgid "Download %d URL"
msgstr ""
#: includes/admin/importers/class-wc-product-csv-importer-controller.php:466
#: includes/export/class-wc-product-csv-exporter.php:552
#: includes/export/class-wc-product-csv-exporter.php:557
msgid "Meta: %s"
msgstr ""
@ -9824,7 +9824,7 @@ msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-orders.php:419
#: includes/admin/reports/class-wc-report-downloads.php:82
#: includes/admin/reports/class-wc-report-downloads.php:209
#: includes/admin/reports/class-wc-report-stock.php:168
#: includes/admin/reports/class-wc-report-stock.php:170
#: includes/class-wc-emails.php:376 includes/class-wc-post-types.php:264
#: includes/data-stores/class-wc-product-data-store-cpt.php:96
#: includes/wc-account-functions.php:202 templates/cart/cart.php:35
@ -10028,7 +10028,7 @@ msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-orders.php:122
#: includes/admin/reports/class-wc-report-customer-list.php:213
#: includes/admin/reports/class-wc-report-stock.php:172
#: includes/admin/reports/class-wc-report-stock.php:174
#: includes/wc-account-functions.php:187
msgid "Actions"
msgstr ""
@ -10255,13 +10255,19 @@ msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:274
#: includes/admin/reports/class-wc-report-stock.php:112
#: includes/wc-product-functions.php:802
msgid "On backorder"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:276
#: includes/admin/reports/class-wc-report-stock.php:114
#: includes/wc-formatting-functions.php:1080
#: includes/wc-product-functions.php:800
msgid "In stock"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:306
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:312
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:307
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:313
msgid "Filter by category"
msgstr ""
@ -10289,7 +10295,11 @@ msgstr ""
msgid "Simple product"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:481
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:373
msgid "Filter by stock status"
msgstr ""
#: includes/admin/list-tables/class-wc-admin-list-table-products.php:503
msgid "Sorting"
msgstr ""
@ -11037,15 +11047,15 @@ msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-attributes.php:9
#: includes/admin/meta-boxes/views/html-product-data-attributes.php:51
#: includes/admin/meta-boxes/views/html-product-data-variations.php:88
#: includes/admin/meta-boxes/views/html-product-data-variations.php:123
#: includes/admin/meta-boxes/views/html-product-data-variations.php:89
#: includes/admin/meta-boxes/views/html-product-data-variations.php:124
msgid "Expand"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-attributes.php:9
#: includes/admin/meta-boxes/views/html-product-data-attributes.php:51
#: includes/admin/meta-boxes/views/html-product-data-variations.php:88
#: includes/admin/meta-boxes/views/html-product-data-variations.php:123
#: includes/admin/meta-boxes/views/html-product-data-variations.php:89
#: includes/admin/meta-boxes/views/html-product-data-variations.php:124
msgid "Close"
msgstr ""
@ -11114,7 +11124,7 @@ msgid "Leave blank for unlimited re-downloads."
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-general.php:116
#: includes/admin/meta-boxes/views/html-product-data-variations.php:78
#: includes/admin/meta-boxes/views/html-product-data-variations.php:79
#: includes/admin/meta-boxes/views/html-variation-admin.php:381
msgid "Download expiry"
msgstr ""
@ -11167,7 +11177,7 @@ msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-inventory.php:28
#: includes/admin/meta-boxes/views/html-variation-admin.php:87
#: includes/admin/views/html-bulk-edit-product.php:234
#: includes/admin/views/html-quick-edit-product.php:179
#: includes/admin/views/html-quick-edit-product.php:166
msgid "Manage stock?"
msgstr ""
@ -11201,7 +11211,7 @@ msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-inventory.php:69
#: includes/admin/meta-boxes/views/html-variation-admin.php:206
#: includes/admin/reports/class-wc-report-stock.php:171
#: includes/admin/reports/class-wc-report-stock.php:173
msgid "Stock status"
msgstr ""
@ -11244,7 +11254,7 @@ msgid "Product Type"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-shipping.php:13
#: includes/admin/meta-boxes/views/html-product-data-variations.php:74
#: includes/admin/meta-boxes/views/html-product-data-variations.php:75
#: includes/admin/views/html-bulk-edit-product.php:118
#: includes/admin/views/html-quick-edit-product.php:99
#: templates/single-product/product-attributes.php:28
@ -11262,21 +11272,21 @@ msgid "Dimensions (%s)"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-shipping.php:27
#: includes/admin/meta-boxes/views/html-product-data-variations.php:71
#: includes/admin/meta-boxes/views/html-product-data-variations.php:72
#: includes/admin/meta-boxes/views/html-variation-admin.php:249
#: includes/admin/views/html-quick-edit-product.php:112
msgid "Length"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-shipping.php:28
#: includes/admin/meta-boxes/views/html-product-data-variations.php:72
#: includes/admin/meta-boxes/views/html-product-data-variations.php:73
#: includes/admin/meta-boxes/views/html-variation-admin.php:250
#: includes/admin/views/html-quick-edit-product.php:113
msgid "Width"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-shipping.php:29
#: includes/admin/meta-boxes/views/html-product-data-variations.php:73
#: includes/admin/meta-boxes/views/html-product-data-variations.php:74
#: includes/admin/meta-boxes/views/html-variation-admin.php:251
#: includes/admin/views/html-quick-edit-product.php:114
msgid "Height"
@ -11391,51 +11401,55 @@ msgstr ""
msgid "Set Status - Out of stock"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:82
#: includes/admin/meta-boxes/views/html-product-data-variations.php:69
msgid "Set Status - On backorder"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:83
#: includes/admin/views/html-report-by-date.php:60
msgid "Go"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:86
#: includes/admin/meta-boxes/views/html-product-data-variations.php:121
#: includes/admin/meta-boxes/views/html-product-data-variations.php:87
#: includes/admin/meta-boxes/views/html-product-data-variations.php:122
#. translators: variations count
msgid "%s item"
msgid_plural "%s items"
msgstr[0] ""
msgstr[1] ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:91
#: includes/admin/meta-boxes/views/html-product-data-variations.php:126
#: includes/admin/meta-boxes/views/html-product-data-variations.php:92
#: includes/admin/meta-boxes/views/html-product-data-variations.php:127
msgid "Go to the first page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:92
#: includes/admin/meta-boxes/views/html-product-data-variations.php:127
#: includes/admin/meta-boxes/views/html-product-data-variations.php:93
#: includes/admin/meta-boxes/views/html-product-data-variations.php:128
msgid "Go to the previous page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:94
#: includes/admin/meta-boxes/views/html-product-data-variations.php:129
msgid "Select Page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:95
#: includes/admin/meta-boxes/views/html-product-data-variations.php:130
msgid "Select Page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:96
#: includes/admin/meta-boxes/views/html-product-data-variations.php:131
#: includes/admin/settings/views/html-settings-tax.php:120
msgid "Current page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:102
#: includes/admin/meta-boxes/views/html-product-data-variations.php:137
#: includes/admin/meta-boxes/views/html-product-data-variations.php:103
#: includes/admin/meta-boxes/views/html-product-data-variations.php:138
msgid "Go to the next page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:103
#: includes/admin/meta-boxes/views/html-product-data-variations.php:138
#: includes/admin/meta-boxes/views/html-product-data-variations.php:104
#: includes/admin/meta-boxes/views/html-product-data-variations.php:139
msgid "Go to the last page"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:116
#: includes/admin/meta-boxes/views/html-product-data-variations.php:117
#: includes/admin/settings/views/html-admin-page-shipping-zone-methods.php:96
#: includes/admin/settings/views/html-admin-page-shipping-zone-methods.php:148
#: includes/admin/settings/views/html-keys-edit.php:105
@ -12051,19 +12065,19 @@ msgstr ""
msgid "No products found."
msgstr ""
#: includes/admin/reports/class-wc-report-stock.php:138
#: includes/admin/reports/class-wc-report-stock.php:140
#: includes/admin/views/html-admin-page-status-logs.php:30
#: includes/wc-account-functions.php:263
msgid "View"
msgstr ""
#: includes/admin/reports/class-wc-report-stock.php:150
#: includes/admin/reports/class-wc-report-stock.php:152
#: includes/widgets/class-wc-widget-product-tag-cloud.php:86
#. translators: %s: product count
msgid "%s product"
msgstr ""
#: includes/admin/reports/class-wc-report-stock.php:170
#: includes/admin/reports/class-wc-report-stock.php:172
msgid "Units in stock"
msgstr ""
@ -12574,7 +12588,7 @@ msgid "Recipient(s)"
msgstr ""
#: includes/admin/settings/class-wc-settings-emails.php:263
#: includes/class-wc-install.php:749
#: includes/class-wc-install.php:750
msgid "Customer"
msgstr ""
@ -14783,12 +14797,12 @@ msgstr ""
#: includes/admin/views/html-bulk-edit-product.php:253
#: includes/admin/views/html-bulk-edit-product.php:269
#: includes/admin/views/html-quick-edit-product.php:183
#: includes/admin/views/html-quick-edit-product.php:187
msgid "Stock qty"
msgstr ""
#: includes/admin/views/html-bulk-edit-product.php:274
#: includes/admin/views/html-quick-edit-product.php:193
#: includes/admin/views/html-quick-edit-product.php:196
msgid "Backorders?"
msgstr ""
@ -14902,7 +14916,7 @@ msgid ""
msgstr ""
#: includes/admin/views/html-notice-tracking.php:13
#: includes/wc-product-functions.php:815
#: includes/wc-product-functions.php:816
msgid "Allow"
msgstr ""
@ -19898,43 +19912,43 @@ msgstr ""
msgid "Please enter a stronger password."
msgstr ""
#: includes/class-wc-install.php:340
#: includes/class-wc-install.php:341
msgid "Monthly"
msgstr ""
#: includes/class-wc-install.php:758
#: includes/class-wc-install.php:759
msgid "Shop manager"
msgstr ""
#: includes/class-wc-install.php:941
#: includes/class-wc-install.php:942
msgid "View WooCommerce settings"
msgstr ""
#: includes/class-wc-install.php:957
#: includes/class-wc-install.php:958
msgid "View WooCommerce documentation"
msgstr ""
#: includes/class-wc-install.php:957
#: includes/class-wc-install.php:958
msgid "Docs"
msgstr ""
#: includes/class-wc-install.php:958
#: includes/class-wc-install.php:959
msgid "View WooCommerce API docs"
msgstr ""
#: includes/class-wc-install.php:958
#: includes/class-wc-install.php:959
msgid "API docs"
msgstr ""
#: includes/class-wc-install.php:959
#: includes/class-wc-install.php:960
msgid "Visit premium customer support"
msgstr ""
#: includes/class-wc-install.php:959
#: includes/class-wc-install.php:960
msgid "Premium support"
msgstr ""
#: includes/class-wc-install.php:1111 includes/class-wc-install.php:1198
#: includes/class-wc-install.php:1112 includes/class-wc-install.php:1199
#. translators: 1: plugin name, 2: error message, 3: URL to install plugin
#. manually.
#. translators: 1: theme slug, 2: error message, 3: URL to install theme
@ -19944,7 +19958,7 @@ msgid ""
"manually by clicking here.</a>"
msgstr ""
#: includes/class-wc-install.php:1138
#: includes/class-wc-install.php:1139
#. translators: 1: plugin name, 2: URL to WP plugin page.
msgid ""
"%1$s was installed but could not be activated. <a href=\"%2$s\">Please "
@ -21826,23 +21840,23 @@ msgstr ""
msgid "Unable to use image \"%s\"."
msgstr ""
#: includes/import/class-wc-product-csv-importer.php:798
#: includes/import/class-wc-product-csv-importer.php:803
msgid "ID %d"
msgstr ""
#: includes/import/class-wc-product-csv-importer.php:801
#: includes/import/class-wc-product-csv-importer.php:806
msgid "SKU %s"
msgstr ""
#: includes/import/class-wc-product-csv-importer.php:844
#: includes/import/class-wc-product-csv-importer.php:849
msgid "A product with this ID already exists."
msgstr ""
#: includes/import/class-wc-product-csv-importer.php:849
#: includes/import/class-wc-product-csv-importer.php:854
msgid "A product with this SKU already exists."
msgstr ""
#: includes/import/class-wc-product-csv-importer.php:854
#: includes/import/class-wc-product-csv-importer.php:859
msgid "No matching product exists to update."
msgstr ""
@ -23094,11 +23108,11 @@ msgstr ""
msgid "Search results only"
msgstr ""
#: includes/wc-product-functions.php:813
#: includes/wc-product-functions.php:814
msgid "Do not allow"
msgstr ""
#: includes/wc-product-functions.php:814
#: includes/wc-product-functions.php:815
msgid "Allow, but notify customer"
msgstr ""
@ -24453,8 +24467,8 @@ msgctxt "Tax status"
msgid "None"
msgstr ""
#: includes/admin/meta-boxes/views/html-product-data-variations.php:100
#: includes/admin/meta-boxes/views/html-product-data-variations.php:135
#: includes/admin/meta-boxes/views/html-product-data-variations.php:101
#: includes/admin/meta-boxes/views/html-product-data-variations.php:136
msgctxt "number of pages"
msgid "of"
msgstr ""
@ -24508,47 +24522,47 @@ msgctxt "Item name in quotes"
msgid "&ldquo;%s&rdquo;"
msgstr ""
#: includes/class-wc-install.php:379
#: includes/class-wc-install.php:380
msgctxt "Page slug"
msgid "shop"
msgstr ""
#: includes/class-wc-install.php:384
#: includes/class-wc-install.php:385
msgctxt "Page slug"
msgid "cart"
msgstr ""
#: includes/class-wc-install.php:389
#: includes/class-wc-install.php:390
msgctxt "Page slug"
msgid "checkout"
msgstr ""
#: includes/class-wc-install.php:394
#: includes/class-wc-install.php:395
msgctxt "Page slug"
msgid "my-account"
msgstr ""
#: includes/class-wc-install.php:380
#: includes/class-wc-install.php:381
msgctxt "Page title"
msgid "Shop"
msgstr ""
#: includes/class-wc-install.php:385
#: includes/class-wc-install.php:386
msgctxt "Page title"
msgid "Cart"
msgstr ""
#: includes/class-wc-install.php:390
#: includes/class-wc-install.php:391
msgctxt "Page title"
msgid "Checkout"
msgstr ""
#: includes/class-wc-install.php:395
#: includes/class-wc-install.php:396
msgctxt "Page title"
msgid "My account"
msgstr ""
#: includes/class-wc-install.php:472 includes/class-wc-install.php:478
#: includes/class-wc-install.php:473 includes/class-wc-install.php:479
msgctxt "Default category slug"
msgid "Uncategorized"
msgstr ""

View File

@ -945,8 +945,14 @@ class WC_Product extends WC_Abstract_Legacy_Product {
*
* @param string $status New status.
*/
public function set_stock_status( $status = '' ) {
$this->set_prop( 'stock_status', 'outofstock' === $status ? 'outofstock' : 'instock' );
public function set_stock_status( $status = 'instock' ) {
$valid_statuses = wc_get_product_stock_status_options();
if ( isset( $valid_statuses[ $status ] ) ) {
$this->set_prop( 'stock_status', $status );
} else {
$this->set_prop( 'stock_status', 'instock' );
}
}
/**
@ -1300,11 +1306,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->set_backorders( 'no' );
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) && 'no' === $this->get_backorders() ) {
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' === $this->get_backorders() ) {
$this->set_stock_status( 'outofstock' );
// If we are stock managing, backorders are allowed, and we don't have stock, force on backorder status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'onbackorder' );
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount', 0 ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
$this->set_stock_status( 'instock' );
}
}
@ -1488,12 +1498,13 @@ class WC_Product extends WC_Abstract_Legacy_Product {
}
/**
* Returns whether or not the product is in stock.
* Returns whether or not the product can be purchased.
* This returns true for 'instock' and 'onbackorder' stock statuses.
*
* @return bool
*/
public function is_in_stock() {
return apply_filters( 'woocommerce_product_is_in_stock', 'instock' === $this->get_stock_status(), $this );
return apply_filters( 'woocommerce_product_is_in_stock', 'outofstock' !== $this->get_stock_status(), $this );
}
/**
@ -1560,6 +1571,10 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @return bool
*/
public function is_on_backorder( $qty_in_cart = 0 ) {
if ( 'onbackorder' === $this->get_stock_status() ) {
return true;
}
return $this->managing_stock() && $this->backorders_allowed() && ( $this->get_stock_quantity() - $qty_in_cart ) < 0 ? true : false;
}

View File

@ -270,7 +270,9 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* Render columm: is_in_stock.
*/
protected function render_is_in_stock_column() {
if ( $this->object->is_in_stock() ) {
if ( $this->object->is_on_backorder() ) {
$stock_html = '<mark class="onbackorder">' . __( 'On backorder', 'woocommerce' ) . '</mark>';
} elseif ( $this->object->is_in_stock() ) {
$stock_html = '<mark class="instock">' . __( 'In stock', 'woocommerce' ) . '</mark>';
} else {
$stock_html = '<mark class="outofstock">' . __( 'Out of stock', 'woocommerce' ) . '</mark>';
@ -298,7 +300,6 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {
// Category Filtering.
$categories_count = (int) wp_count_terms( 'product_cat' );
if ( $categories_count <= apply_filters( 'woocommerce_product_category_filter_threshold', 100 ) ) {
@ -317,7 +318,6 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
<?php
}
// Product type filtering.
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
$terms = get_terms( 'product_type' );
$output = '<select name="product_type" id="dropdown_product_type"><option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
@ -368,6 +368,16 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$output .= '</select>';
$current_stock_status = isset( $_REQUEST['stock_status'] ) ? wc_clean( wp_unslash( $_REQUEST['stock_status'] ) ): false; // WPCS: input var ok, sanitization ok.
$stock_statuses = wc_get_product_stock_status_options();
$output .= '<select name="stock_status"><option value="">' . esc_html__( 'Filter by stock status', 'woocommerce' ) . '</option>';
foreach ( $stock_statuses as $status => $label ) {
$output .= '<option ' . selected( $status, $current_stock_status, false ) . ' value="' . esc_attr( $status ) . '">' . esc_html( $label ) . '</option>';
}
$output .= '</select>';
echo apply_filters( 'woocommerce_product_filters', $output ); // WPCS: XSS ok.
}
@ -378,6 +388,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* @return array
*/
protected function query_filters( $query_vars ) {
if ( isset( $query_vars['orderby'] ) ) {
if ( 'price' === $vars['orderby'] ) {
// @codingStandardsIgnoreStart
@ -420,6 +431,17 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
);
}
if ( ! empty( $_GET['stock_status'] ) ) {
if ( ! isset( $query_vars['meta_query'] ) ) {
$query_vars['meta_query'] = array();
}
$query_vars['meta_query'][] = array(
'key' => '_stock_status',
'value' => wc_clean( wp_unslash( $_GET['stock_status'] ) ),
);
}
return $query_vars;
}

View File

@ -65,7 +65,7 @@ if ( ! defined( 'ABSPATH' ) ) {
woocommerce_wp_select( array(
'id' => '_stock_status',
'value' => $product_object->get_stock_status( 'edit' ),
'wrapper_class' => 'hide_if_variable hide_if_external',
'wrapper_class' => 'stock_status_field hide_if_variable hide_if_external',
'label' => __( 'Stock status', 'woocommerce' ),
'options' => wc_get_product_stock_status_options(),
'desc_tip' => true,

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( ! count( $variation_attributes ) ) : ?>
<div id="message" class="inline notice woocommerce-message">
<p><?php esc_html_e( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ); ?></p>
<p><?php echo wp_kses_post( __( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ) ); ?></p>
<p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php esc_html_e( 'Learn more', 'woocommerce' ); ?></a></p>
</div>
@ -62,10 +62,11 @@ if ( ! defined( 'ABSPATH' ) ) {
<option value="variable_sale_schedule"><?php esc_html_e( 'Set scheduled sale dates', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Inventory', 'woocommerce' ); ?>">
<option value="toggle_manage_stock"><?php esc_html_e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option>
<option value="variable_stock"><?php esc_html_e( 'Stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_instock"><?php esc_html_e( 'Set Status - In stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_outofstock"><?php esc_html_e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
<option value="toggle_manage_stock"><?php _e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option>
<option value="variable_stock"><?php _e( 'Stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_instock"><?php _e( 'Set Status - In stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_outofstock"><?php _e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_onbackorder"><?php _e( 'Set Status - On backorder', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Shipping', 'woocommerce' ); ?>">
<option value="variable_length"><?php esc_html_e( 'Length', 'woocommerce' ); ?></option>

View File

@ -108,7 +108,9 @@ class WC_Report_Stock extends WP_List_Table {
break;
case 'stock_status' :
if ( $product->is_in_stock() ) {
if ( $product->is_on_backorder() ) {
$stock_html = '<mark class="onbackorder">' . __( 'On backorder', 'woocommerce' ) . '</mark>';
} elseif ( $product->is_in_stock() ) {
$stock_html = '<mark class="instock">' . __( 'In stock', 'woocommerce' ) . '</mark>';
} else {
$stock_html = '<mark class="outofstock">' . __( 'Out of stock', 'woocommerce' ) . '</mark>';

View File

@ -12,14 +12,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<fieldset class="inline-edit-col-left">
<div id="woocommerce-fields" class="inline-edit-col">
<h4><?php _e( 'Product data', 'woocommerce' ); ?></h4>
<h4><?php esc_html_e( 'Product data', 'woocommerce' ); ?></h4>
<?php do_action( 'woocommerce_product_quick_edit_start' ); ?>
<?php if ( wc_product_sku_enabled() ) : ?>
<label>
<span class="title"><?php _e( 'SKU', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'SKU', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_sku" class="text sku" value="">
</span>
@ -30,14 +30,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="price_fields">
<label>
<span class="title"><?php _e( 'Price', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Price', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_regular_price" class="text wc_input_price regular_price" placeholder="<?php esc_attr_e( 'Regular price', 'woocommerce' ); ?>" value="">
</span>
</label>
<br class="clear" />
<label>
<span class="title"><?php _e( 'Sale', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Sale', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_sale_price" class="text wc_input_price sale_price" placeholder="<?php esc_attr_e( 'Sale price', 'woocommerce' ); ?>" value="">
</span>
@ -47,7 +47,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_tax_enabled() ) : ?>
<label class="alignleft">
<span class="title"><?php _e( 'Tax status', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Tax status', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="tax_status" name="_tax_status">
<?php
@ -57,7 +57,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'none' => _x( 'None', 'Tax status', 'woocommerce' ),
);
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
@ -65,7 +65,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</label>
<br class="clear" />
<label class="alignleft">
<span class="title"><?php _e( 'Tax class', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Tax class', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="tax_class" name="_tax_class">
<?php
@ -96,7 +96,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_product_weight_enabled() ) : ?>
<label>
<span class="title"><?php _e( 'Weight', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Weight', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_weight" class="text weight" placeholder="<?php echo wc_format_localized_decimal( 0 ); ?>" value="">
</span>
@ -107,7 +107,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_product_dimensions_enabled() ) : ?>
<div class="inline-edit-group dimensions">
<div>
<span class="title"><?php _e( 'L/W/H', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'L/W/H', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_length" class="text wc_input_decimal length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" value="">
<input type="text" name="_width" class="text wc_input_decimal width" placeholder="<?php esc_attr_e( 'Width', 'woocommerce' ); ?>" value="">
@ -120,51 +120,61 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
<?php endif; ?>
<label class="alignleft">
<span class="title"><?php _e( 'Shipping class', 'woocommerce' ); ?></span>
<div class="inline-edit-group">
<span class="title"><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="shipping_class" name="_shipping_class">
<option value="_no_shipping_class"><?php _e( 'No shipping class', 'woocommerce' ); ?></option>
<option value="_no_shipping_class"><?php esc_html_e( 'No shipping class', 'woocommerce' ); ?></option>
<?php
foreach ( $shipping_class as $key => $value ) {
echo '<option value="' . esc_attr( $value->slug ) . '">' . $value->name . '</option>';
echo '<option value="' . esc_attr( $value->slug ) . '">' . esc_html( $value->name ) . '</option>';
}
?>
</select>
</span>
</label>
<br class="clear" />
</div>
<label class="alignleft">
<span class="title"><?php _e( 'Visibility', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="visibility" name="_visibility">
<?php
$options = apply_filters( 'woocommerce_product_visibility_options', array(
'visible' => __( 'Catalog &amp; search', 'woocommerce' ),
'catalog' => __( 'Catalog', 'woocommerce' ),
'search' => __( 'Search', 'woocommerce' ),
'hidden' => __( 'Hidden', 'woocommerce' ),
) );
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
}
?>
</select>
</span>
</label>
<label class="alignleft featured">
<input type="checkbox" name="_featured" value="1">
<span class="checkbox-title"><?php _e( 'Featured', 'woocommerce' ); ?></span>
</label>
<br class="clear" />
<label class="alignleft">
<span class="title"><?php _e( 'In stock?', 'woocommerce' ); ?></span>
<div class="inline-edit-group">
<label class="alignleft">
<span class="title"><?php esc_html_e( 'Visibility', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="visibility" name="_visibility">
<?php
$options = apply_filters( 'woocommerce_product_visibility_options', array(
'visible' => __( 'Catalog &amp; search', 'woocommerce' ),
'catalog' => __( 'Catalog', 'woocommerce' ),
'search' => __( 'Search', 'woocommerce' ),
'hidden' => __( 'Hidden', 'woocommerce' ),
) );
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
</span>
</label>
<label class="alignleft featured">
<input type="checkbox" name="_featured" value="1">
<span class="checkbox-title"><?php esc_html_e( 'Featured', 'woocommerce' ); ?></span>
</label>
</div>
<?php if ( get_option( 'woocommerce_manage_stock' ) == 'yes' ) : ?>
<div class="inline-edit-group">
<label class="manage_stock">
<input type="checkbox" name="_manage_stock" value="1">
<span class="checkbox-title"><?php esc_html_e( 'Manage stock?', 'woocommerce' ); ?></span>
</label>
</div>
<?php endif; ?>
<label class="stock_status_field">
<span class="title"><?php esc_html_e( 'In stock?', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="stock_status" name="_stock_status">
<?php
foreach ( wc_get_product_stock_status_options() as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
@ -172,30 +182,23 @@ if ( ! defined( 'ABSPATH' ) ) {
</label>
<div class="stock_fields">
<?php if ( get_option( 'woocommerce_manage_stock' ) == 'yes' ) : ?>
<label class="alignleft manage_stock">
<input type="checkbox" name="_manage_stock" value="1">
<span class="checkbox-title"><?php _e( 'Manage stock?', 'woocommerce' ); ?></span>
</label>
<br class="clear" />
<label class="stock_qty_field">
<span class="title"><?php _e( 'Stock qty', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Stock qty', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="number" name="_stock" class="text stock" step="any" value="">
</span>
</label>
<?php endif; ?>
</div>
<label class="alignleft">
<span class="title"><?php _e( 'Backorders?', 'woocommerce' ); ?></span>
<label class="alignleft backorder_field">
<span class="title"><?php esc_html_e( 'Backorders?', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="backorders" name="_backorders">
<?php
foreach ( wc_get_product_backorder_options() as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>

View File

@ -1965,6 +1965,17 @@ class WC_AJAX {
self::variation_bulk_set( $variations, 'stock_status', 'outofstock' );
}
/**
* Bulk action - Set Stock Status as On Backorder.
* @access private
* @used-by bulk_edit_variations
* @param array $variations
* @param array $data
*/
private static function variation_bulk_action_variable_stock_status_onbackorder( $variations, $data ) {
self::variation_bulk_set( $variations, 'stock_status', 'onbackorder' );
}
/**
* Bulk action - Set Stock.
* @access private

View File

@ -98,6 +98,7 @@ class WC_Install {
),
'3.3.0' => array(
'wc_update_330_image_options',
'wc_update_330_product_stock_status',
'wc_update_330_set_default_product_cat',
'wc_update_330_db_version',
),

View File

@ -376,21 +376,21 @@ class WC_Product_Variable extends WC_Product {
if ( ! $this->get_manage_stock() ) {
$this->set_stock_quantity( '' );
$this->set_backorders( 'no' );
$this->set_stock_status( $this->child_is_in_stock() ? 'instock' : 'outofstock' );
$this->data_store->sync_stock_status( $this );
// If backorders are enabled, always in stock.
} elseif ( 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'instock' );
// If we are stock managing, backorders are allowed, and we don't have stock, force on backorder status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'onbackorder' );
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' === $this->get_backorders() ) {
$this->set_stock_status( 'outofstock' );
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount', 0 ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
$this->set_stock_status( 'instock' );
// Otherwise revert to status the children have.
// Otherwise revert to status the children have.
} else {
$this->set_stock_status( $this->child_is_in_stock() ? 'instock' : 'outofstock' );
}
@ -451,6 +451,16 @@ class WC_Product_Variable extends WC_Product {
return $this->data_store->child_is_in_stock( $this );
}
/**
* Is a child on backorder?
*
* @since 3.3.0
* @return boolean
*/
public function child_is_on_backorder() {
return $this->data_store->child_has_stock_status( $this, 'onbackorder' );
}
/**
* Does a child have a weight set?
* @return boolean

View File

@ -125,15 +125,19 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
$children = get_transient( $children_transient_name );
if ( empty( $children ) || ! is_array( $children ) || ! isset( $children['all'] ) || ! isset( $children['visible'] ) || $force_read ) {
$all_args = $visible_only_args = array(
$all_args = array(
'post_parent' => $product->get_id(),
'post_type' => 'product_variation',
'orderby' => array( 'menu_order' => 'ASC', 'ID' => 'ASC' ),
'orderby' => array(
'menu_order' => 'ASC',
'ID' => 'ASC',
),
'fields' => 'ids',
'post_status' => array( 'publish', 'private' ),
'numberposts' => -1,
);
$visible_only_args = $all_args;
$visible_only_args['post_status'] = 'publish';
if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
@ -380,10 +384,24 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
* @return boolean
*/
public function child_is_in_stock( $product ) {
return $this->child_has_stock_status( $product, 'instock' );
}
/**
* Does a child have a stock status?
*
* @since 3.3.0
* @param WC_Product $product Product object.
* @param string $status 'instock', 'outofstock', or 'onbackorder'.
* @return boolean
*/
public function child_has_stock_status( $product, $status ) {
global $wpdb;
$children = $product->get_children();
$oufofstock_children = $children ? $wpdb->get_var( "SELECT COUNT( post_id ) FROM $wpdb->postmeta WHERE meta_key = '_stock_status' AND meta_value = 'outofstock' AND post_id IN ( " . implode( ',', array_map( 'absint', $children ) ) . ' )' ) : 0;
return count( $children ) > $oufofstock_children;
$children = $product->get_children();
$children_with_status = $children ? $wpdb->get_var( "SELECT COUNT( post_id ) FROM $wpdb->postmeta WHERE meta_key = '_stock_status' AND meta_value = '" . esc_sql( $status ) . "' AND post_id IN ( " . implode( ',', array_map( 'absint', $children ) ) . ' )' ) : 0;
return (bool) $children_with_status;
}
/**
@ -474,7 +492,13 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
* @param WC_Product $product Product object.
*/
public function sync_stock_status( &$product ) {
$product->set_stock_status( $product->child_is_in_stock() ? 'instock' : 'outofstock' );
if ( $product->child_is_in_stock() ) {
$product->set_stock_status( 'instock' );
} elseif ( $product->child_is_on_backorder() ) {
$product->set_stock_status( 'onbackorder' );
} else {
$product->set_stock_status( 'outofstock' );
}
}
/**

View File

@ -383,6 +383,11 @@ class WC_Product_CSV_Exporter extends WC_CSV_Batch_Exporter {
*/
protected function get_column_value_stock_status( $product ) {
$status = $product->get_stock_status( 'edit' );
if ( 'onbackorder' === $status ) {
return 'backorder';
}
return 'instock' === $status ? 1 : 0;
}

View File

@ -726,4 +726,24 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
protected function explode_values_formatter( $value ) {
return trim( str_replace( '::separator::', ',', $value ) );
}
/**
* The exporter prepends a ' to fields that start with a - which causes
* issues with negative numbers. This removes the ' if the input is still a valid
* number after removal.
*
* @since 3.3.0
* @param string $value A numeric string that may or may not have ' prepended.
* @return string
*/
protected function unescape_negative_number( $value ) {
if ( 0 === strpos( $value, "'-" ) ) {
$unescaped = substr_replace( $value, '', 0, 1 );
if ( is_numeric( $unescaped ) ) {
return $unescaped;
}
}
return $value;
}
}

View File

@ -280,6 +280,9 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
return $value;
}
// Remove the ' prepended to fields that start with - if needed.
$value = $this->unescape_negative_number( $value );
return floatval( $value );
}
@ -294,6 +297,9 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
return $value;
}
// Remove the ' prepended to fields that start with - if needed.
$value = $this->unescape_negative_number( $value );
return wc_stock_amount( $value );
}
@ -633,17 +639,16 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
$data['stock_status'] = isset( $data['stock_status'] ) ? $data['stock_status'] : true;
} else {
$data['manage_stock'] = true;
// Only auto set status when stock_status is empty.
if ( ! isset( $data['stock_status'] ) || isset( $data['stock_status'] ) && '' === $data['stock_status'] ) {
$data['stock_status'] = 0 < $data['stock_quantity'];
}
}
}
// Stock is bool.
// Stock is bool or 'backorder'.
if ( isset( $data['stock_status'] ) ) {
$data['stock_status'] = $data['stock_status'] ? 'instock' : 'outofstock';
if ( 'backorder' === $data['stock_status'] ) {
$data['stock_status'] = 'onbackorder';
} else {
$data['stock_status'] = $data['stock_status'] ? 'instock' : 'outofstock';
}
}
// Prepare grouped products.

View File

@ -797,8 +797,9 @@ function wc_get_product_tax_class_options() {
*/
function wc_get_product_stock_status_options() {
return array(
'instock' => __( 'In stock', 'woocommerce' ),
'outofstock' => __( 'Out of stock', 'woocommerce' ),
'instock' => __( 'In stock', 'woocommerce' ),
'outofstock' => __( 'Out of stock', 'woocommerce' ),
'onbackorder' => __( 'On backorder', 'woocommerce' ),
);
}

View File

@ -1507,6 +1507,44 @@ function wc_update_330_set_default_product_cat() {
}
}
/**
* Update product stock status to use the new onbackorder status.
*/
function wc_update_330_product_stock_status() {
global $wpdb;
if ( 'yes' !== get_option( 'woocommerce_manage_stock' ) ) {
return;
}
$min_stock_amount = (int) get_option( 'woocommerce_notify_no_stock_amount', 0 );
// Get all products that have stock management enabled, stock less than or equal to min stock amount, and backorders enabled.
$post_ids = $wpdb->get_col( $wpdb->prepare( "
SELECT t1.post_id FROM $wpdb->postmeta t1
INNER JOIN $wpdb->postmeta t2
ON t1.post_id = t2.post_id
AND t1.meta_key = '_manage_stock' AND t1.meta_value = 'yes'
AND t2.meta_key = '_stock' AND t2.meta_value <= %d
INNER JOIN $wpdb->postmeta t3
ON t2.post_id = t3.post_id
AND t3.meta_key = '_backorders' AND ( t3.meta_value = 'yes' OR t3.meta_value = 'notify' )
", $min_stock_amount ) ); // WPCS: db call ok, unprepared SQL ok, cache ok.
if ( empty( $post_ids ) ) {
return;
}
$post_ids = array_map( 'absint', $post_ids );
// Set the status to onbackorder for those products.
$wpdb->query( "
UPDATE $wpdb->postmeta
SET meta_value = 'onbackorder'
WHERE meta_key = '_stock_status' AND post_id IN ( " . implode( ',', $post_ids ) . ' )
' ); // WPCS: db call ok, unprepared SQL ok, cache ok.
}
/**
* Update DB Version.
*/

View File

@ -1,6 +1,13 @@
<?php
/**
* Unit tests for the product data methods.
*
* @package WooCommerce\Tests\Product
*/
/**
* Data Functions.
*
* @package WooCommerce\Tests\Product
* @since 3.0.0
*/
@ -8,13 +15,14 @@ class WC_Tests_Product_Data extends WC_Unit_Test_Case {
/**
* Test product setters and getters
*
* @since 3.0.0
*/
public function test_product_getters_and_setters() {
global $wpdb;
$attributes = array();
$attribute = new WC_Product_Attribute();
$attribute = new WC_Product_Attribute();
$attribute->set_id( 0 );
$attribute->set_name( 'Test Attribute' );
$attribute->set_options( array( 'Fish', 'Fingers' ) );
@ -57,7 +65,8 @@ class WC_Tests_Product_Data extends WC_Unit_Test_Case {
'download_expiry' => -1,
'download_limit' => 5,
'attributes' => $attributes,
);
);
$product = new WC_Product();
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
@ -72,16 +81,86 @@ class WC_Tests_Product_Data extends WC_Unit_Test_Case {
$this->assertEquals( $product->get_date_on_sale_from()->getTimestamp(), 1475798400 );
$this->assertEquals( $product->get_date_on_sale_to()->getTimestamp(), 1477267200 );
$image_url = media_sideload_image( "https://cldup.com/Dr1Bczxq4q.png", $product->get_id(), '', 'src' );
$image_url = media_sideload_image( 'https://cldup.com/Dr1Bczxq4q.png', $product->get_id(), '', 'src' );
$image_id = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE guid='%s';", $image_url ) );
$product->set_image_id( $image_id[0] );
$product->save();
$this->assertEquals( $image_id[0], $product->get_image_id() );
$product->delete( true );
}
}
/**
* Test the onbackorder stock status.
*
* @since 3.3.0
*/
public function test_product_backorder_stock_status() {
$product = new WC_Product();
$product->set_stock_status( 'onbackorder' );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
$product->save();
$product = new WC_Product( $product->get_id() );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
}
/**
* Test the automatic stock status transitions done on product save.
*
* @since 3.3.0
*/
public function test_product_auto_stock_status() {
$product = new WC_Product();
// Product should not have quantity and stock status should not be updated automatically if not managing stock.
$product->set_manage_stock( false );
$product->set_stock_quantity( 5 );
$product->set_stock_status( 'instock' );
$product->save();
$this->assertEquals( '', $product->get_stock_quantity() );
$this->assertEquals( 'instock', $product->get_stock_status() );
$product->set_stock_status( 'outofstock' );
$product->save();
$this->assertEquals( 'outofstock', $product->get_stock_status() );
$product->set_manage_stock( true );
// Product should be out of stock if managing orders, no backorders allowed, and quantity too low.
$product->set_stock_quantity( 0 );
$product->set_stock_status( 'instock' );
$product->set_backorders( 'no' );
$product->save();
$this->assertEquals( 0, $product->get_stock_quantity() );
$this->assertEquals( 'outofstock', $product->get_stock_status() );
// Product should be on backorder if managing orders, backorders allowed, and quantity too low.
$product->set_stock_quantity( 0 );
$product->set_stock_status( 'instock' );
$product->set_backorders( 'yes' );
$product->save();
$this->assertEquals( 0, $product->get_stock_quantity() );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
// Product should go to in stock if backordered and inventory increases.
$product->set_stock_quantity( 5 );
$product->set_stock_status( 'onbackorder' );
$product->set_backorders( 'notify' );
$product->save();
$this->assertEquals( 5, $product->get_stock_quantity() );
$this->assertEquals( 'instock', $product->get_stock_status() );
// Product should go to in stock if out of stock and inventory increases.
$product->set_stock_quantity( 3 );
$product->set_stock_status( 'outofstock' );
$product->set_backorders( 'no' );
$product->save();
$this->assertEquals( 3, $product->get_stock_quantity() );
$this->assertEquals( 'instock', $product->get_stock_status() );
}
/**
* Test product term setters and getters
*
* @since 3.0.0
*/
public function test_product_term_getters_and_setters() {
@ -95,7 +174,9 @@ class WC_Tests_Product_Data extends WC_Unit_Test_Case {
'tag_ids' => array( $test_tag_1['term_id'], $test_tag_2['term_id'] ),
'category_ids' => array( $test_cat_1['term_id'], $test_cat_2['term_id'] ),
);
$product = new WC_Product_Simple;
$product = new WC_Product_Simple();
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
}
@ -110,33 +191,37 @@ class WC_Tests_Product_Data extends WC_Unit_Test_Case {
*
* @since 3.0.0
*/
public function test_grouped_product_getters_and_setters() {
public function test_grouped_product_getters_and_setters() {
$getters_and_setters = array(
'children' => array( 1, 2, 3 ),
);
$product = new WC_Product_Grouped;
$product = new WC_Product_Grouped();
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
$this->assertEquals( $value, $product->{"get_{$function}"}(), $function );
}
}
}
/**
* Test external product setters and getters
*
* @since 3.0.0
*/
public function test_external_product_getters_and_setters() {
$time = time();
$getters_and_setters = array(
'button_text' => 'Test Button Text',
'product_url' => 'https://wordpress.org',
);
$product = new WC_Product_External;
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
$this->assertEquals( $value, $product->{"get_{$function}"}(), $function );
}
}
public function test_external_product_getters_and_setters() {
$time = time();
$getters_and_setters = array(
'button_text' => 'Test Button Text',
'product_url' => 'https://wordpress.org',
);
$product = new WC_Product_External();
foreach ( $getters_and_setters as $function => $value ) {
$product->{"set_{$function}"}( $value );
$this->assertEquals( $value, $product->{"get_{$function}"}(), $function );
}
}
}

View File

@ -1,9 +1,12 @@
<?php
/**
* Unit tests for the WC_Product_Variable class.
*
* @package WooCommerce\Tests\Product
*/
/**
* Class WC_Tests_Product_Variable.
*
* @package WooCommerce\Tests\Product
*/
class WC_Tests_Product_Variable extends WC_Unit_Test_Case {
@ -15,9 +18,117 @@ class WC_Tests_Product_Variable extends WC_Unit_Test_Case {
$product_id = $product->save();
$prices = $product->get_variation_prices();
$this->assertArrayHasKey( 'regular_price', $prices );
$this->assertArrayHasKey( 'sale_price', $prices );
$this->assertArrayHasKey( 'price', $prices );
$this->assertArrayHasKey( 'regular_price', $prices );
$this->assertArrayHasKey( 'sale_price', $prices );
$this->assertArrayHasKey( 'price', $prices );
$this->assertTrue( $product_id > 0 );
}
/**
* Test the automatic stock status transitions done on variable product save.
*
* @since 3.3.0
*/
public function test_variable_product_auto_stock_status() {
$product = new WC_Product_Variable();
// Product should not have quantity and stock status should be based on children stock status if not managing stock.
$product->set_manage_stock( false );
$product->set_stock_quantity( 5 );
$product->set_stock_status( 'instock' );
$product->save();
$this->assertEquals( '', $product->get_stock_quantity() );
$this->assertEquals( 'outofstock', $product->get_stock_status() );
$product->set_manage_stock( true );
// Product should be out of stock if managing orders, no backorders allowed, and quantity too low.
$product->set_stock_quantity( 0 );
$product->set_stock_status( 'instock' );
$product->set_backorders( 'no' );
$product->save();
$this->assertEquals( 0, $product->get_stock_quantity() );
$this->assertEquals( 'outofstock', $product->get_stock_status() );
// Product should be on backorder if managing orders, backorders allowed, and quantity too low.
$product->set_stock_quantity( 0 );
$product->set_stock_status( 'instock' );
$product->set_backorders( 'yes' );
$product->save();
$this->assertEquals( 0, $product->get_stock_quantity() );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
// Product should go to in stock if backordered and inventory increases.
$product->set_stock_quantity( 5 );
$product->set_stock_status( 'onbackorder' );
$product->set_backorders( 'notify' );
$product->save();
$this->assertEquals( 5, $product->get_stock_quantity() );
$this->assertEquals( 'instock', $product->get_stock_status() );
// Product should go to in stock if out of stock and inventory increases.
$product->set_stock_quantity( 3 );
$product->set_stock_status( 'outofstock' );
$product->set_backorders( 'no' );
$product->save();
$this->assertEquals( 3, $product->get_stock_quantity() );
$this->assertEquals( 'instock', $product->get_stock_status() );
}
/**
* Test that variable products have the correct status when syncing with their children.
*
* @since 3.3.0
*/
public function test_variable_product_stock_status_sync() {
$product = new WC_Product_Variable();
$product->save();
$child1 = new WC_Product_Variation();
$child1->set_parent_id( $product->get_id() );
$child1->save();
$child2 = new WC_Product_Variation();
$child2->set_parent_id( $product->get_id() );
$child2->save();
$product->set_children( array( $child1->get_id(), $child2->get_id() ) );
// Product should be in stock if a child is in stock.
$child1->set_stock_status( 'instock' );
$child1->save();
$child2->set_stock_status( 'outofstock' );
$child2->save();
WC_Product_Variable::sync( $product );
$this->assertEquals( 'instock', $product->get_stock_status() );
$child2->set_stock_status( 'onbackorder' );
$child2->save();
WC_Product_Variable::sync( $product );
$this->assertEquals( 'instock', $product->get_stock_status() );
// Product should be out of stock if all children are out of stock.
$child1->set_stock_status( 'outofstock' );
$child1->save();
$child2->set_stock_status( 'outofstock' );
$child2->save();
WC_Product_Variable::sync( $product );
$this->assertEquals( 'outofstock', $product->get_stock_status() );
// Product should be on backorder if all children are on backorder.
$child1->set_stock_status( 'onbackorder' );
$child1->save();
$child2->set_stock_status( 'onbackorder' );
$child2->save();
WC_Product_Variable::sync( $product );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
// Product should be on backorder if at least one child is on backorder and the rest are out of stock.
$child1->set_stock_status( 'outofstock' );
$child1->save();
$child2->set_stock_status( 'onbackorder' );
$child2->save();
WC_Product_Variable::sync( $product );
$this->assertEquals( 'onbackorder', $product->get_stock_status() );
}
}

View File

@ -8,7 +8,6 @@
/**
* Class Product_Variation.
*
* @package WooCommerce\Tests\Product
* @since 3.0
*/
class WC_Tests_Product_Variation extends WC_Unit_Test_Case {