diff --git a/changelog/60_UNRELEASED_2020-xx-xx.md b/changelog/60_UNRELEASED_2020-xx-xx.md index 6297038c..d9c13da1 100644 --- a/changelog/60_UNRELEASED_2020-xx-xx.md +++ b/changelog/60_UNRELEASED_2020-xx-xx.md @@ -32,6 +32,7 @@ _- (Because the stock quantity unit is now the base for everything, it cannot be - When creating a quantity unit conversion it's now possible to automatically create the inverse conversion (thanks @kriddles) - On purchase there is now a warning shown, when the best before date of the purchased product is earlier than the next best before date in stock (enabled by default, can be disabled by a new stock setting (top right corner settings menu)) - The amount to be used for the "quick consume/open buttons" on the stock overview page can now be configured per product (new product option "Quick consume amount", defaults to 1) +- Products can now be duplicated (new button on the products list page, all fields will be preset from the copied product, except the name) - Optimized/clarified what the total/unit price is on the purchase page (thanks @kriddles) - On the purchase page the amount field is now displayed above/before the best before date for better `TAB` handling (thanks @kriddles) - Changed that when `FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING` is disabled, products now get internally a best before of "never expires" (aka `2999-12-31`) instead of today (thanks @kriddles) diff --git a/localization/strings.pot b/localization/strings.pot index f1e0c19f..5d1ad3e9 100644 --- a/localization/strings.pot +++ b/localization/strings.pot @@ -1942,3 +1942,9 @@ msgstr "" msgid "This amount is used for the \"quick consume/open buttons\" on the stock overview page (related to quantity unit stock)" msgstr "" + +msgid "Copy this item" +msgstr "" + +msgid "Are you sure to remove this barcode?" +msgstr "" diff --git a/public/viewjs/productform.js b/public/viewjs/productform.js index a8652891..b2213110 100644 --- a/public/viewjs/productform.js +++ b/public/viewjs/productform.js @@ -390,9 +390,6 @@ $(document).on('click', '.qu-conversion-delete-button', function(e) $(document).on('click', '.barcode-delete-button', function(e) { var objectId = $(e.currentTarget).attr('data-barcode-id'); - var productId = $(e.currentTarget).attr('data-product-id'); - var barcode = $(e.currentTarget).attr('data-barcode'); - var productBarcode = $(e.currentTarget).attr('data-product-barcode'); bootbox.confirm({ message: __t('Are you sure to remove this barcode?'), @@ -427,14 +424,15 @@ $(document).on('click', '.barcode-delete-button', function(e) }); }); -$('#qu_id_purchase').blur(function(e) +$('#qu_id_stock').change(function(e) { - // Preset the stock quantity unit with the purchase quantity unit, if the stock quantity unit is unset. - var QuIdStock = $('#qu_id_stock'); - var QuIdPurchase = $('#qu_id_purchase'); - if (QuIdStock[0].selectedIndex === 0 && QuIdPurchase[0].selectedIndex !== 0) + // Preset QU purchase with stock QU if unset + var quIdStock = $('#qu_id_stock'); + var quIdPurchase = $('#qu_id_purchase'); + + if (quIdPurchase[0].selectedIndex === 0 && quIdStock[0].selectedIndex !== 0) { - QuIdStock[0].selectedIndex = QuIdPurchase[0].selectedIndex; + quIdPurchase[0].selectedIndex = quIdStock[0].selectedIndex; Grocy.FrontendHelpers.ValidateForm('product-form'); } }); @@ -448,3 +446,65 @@ $(window).on("message", function(e) window.location.reload(); } }); + +if (Grocy.EditMode == "create" && GetUriParam("copy-of") != undefined) +{ + Grocy.Api.Get('objects/products/' + GetUriParam("copy-of"), + function(sourceProduct) + { + if (sourceProduct.parent_product_id != null) + { + Grocy.Components.ProductPicker.SetId(sourceProduct.parent_product_id); + } + if (sourceProduct.description != null) + { + $("#description").summernote("pasteHTML", sourceProduct.description); + } + $("#location_id").val(sourceProduct.location_id); + if (sourceProduct.shopping_location_id != null) + { + Grocy.Components.ShoppingLocationPicker.SetId(sourceProduct.shopping_location_id); + } + $("#min_stock_amount").val(sourceProduct.min_stock_amount); + if (BoolVal(sourceProduct.cumulate_min_stock_amount_of_sub_products)) + { + $("#cumulate_min_stock_amount_of_sub_products").prop("checked", true); + } + $("#default_best_before_days").val(sourceProduct.default_best_before_days); + $("#default_best_before_days_after_open").val(sourceProduct.default_best_before_days_after_open); + if (sourceProduct.product_group_id != null) + { + $("#product_group_id").val(sourceProduct.product_group_id); + } + $("#qu_id_stock").val(sourceProduct.qu_id_stock); + $("#qu_id_purchase").val(sourceProduct.qu_id_purchase); + $("#qu_factor_purchase_to_stock").val(sourceProduct.qu_factor_purchase_to_stock); + if (BoolVal(sourceProduct.allow_partial_units_in_stock)) + { + $("#allow_partial_units_in_stock").prop("checked", true); + } + if (BoolVal(sourceProduct.enable_tare_weight_handling)) + { + $("#enable_tare_weight_handling").prop("checked", true); + } + $("#tare_weight").val(sourceProduct.tare_weight); + if (BoolVal(sourceProduct.not_check_stock_fulfillment_for_recipes)) + { + $("#not_check_stock_fulfillment_for_recipes").prop("checked", true); + } + if (sourceProduct.calories != null) + { + $("#calories").val(sourceProduct.calories); + } + $("#default_best_before_days_after_freezing").val(sourceProduct.default_best_before_days_after_freezing); + $("#default_best_before_days_after_thawing").val(sourceProduct.default_best_before_days_after_thawing); + $("#quick_consume_amount").val(sourceProduct.quick_consume_amount); + + Grocy.FrontendHelpers.ValidateForm('product-form'); + }, + function(xhr) + { + console.error(xhr); + } + ); +} diff --git a/views/productform.blade.php b/views/productform.blade.php index 40fc8102..2630477e 100644 --- a/views/productform.blade.php +++ b/views/productform.blade.php @@ -185,7 +185,17 @@ 'invalidFeedback' => $__t('The amount cannot be lower than %s', '-1'), 'hint' => $__t('When this product was marked as opened, the best before date will be replaced by today + this amount of days (a value of 0 disables this)') )) + @else + @endif + @else + @endif
@@ -310,6 +320,12 @@
+ @else + + @endif @php if($mode == 'edit') { $value = $product->calories; } else { $value = 0; } @endphp @include('components.numberpicker', array( @@ -323,7 +339,6 @@ 'isRequired' => false, 'additionalCssClasses' => 'locale-number-input locale-number-quantity-amount' )) - @endif @if(GROCY_FEATURE_FLAG_STOCK_PRODUCT_FREEZING) @php if($mode == 'edit') { $value = $product->default_best_before_days_after_freezing; } else { $value = 0; } @endphp diff --git a/views/products.blade.php b/views/products.blade.php index d903580d..65a5cffc 100644 --- a/views/products.blade.php +++ b/views/products.blade.php @@ -118,6 +118,12 @@ title="{{ $__t('Edit this item') }}"> + + +