mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
Make it possible to copy products (closes #571)
This commit is contained in:
parent
7d7f9bf07a
commit
9a7196b761
@ -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)
|
||||
|
@ -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 ""
|
||||
|
@ -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);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -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
|
||||
<input type="hidden"
|
||||
name="default_best_before_days_after_open"
|
||||
id="default_best_before_days_after_open"
|
||||
value="1">
|
||||
@endif
|
||||
@else
|
||||
<input type="hidden"
|
||||
name="default_best_before_days"
|
||||
id="default_best_before_days"
|
||||
value="1">
|
||||
@endif
|
||||
|
||||
<div class="form-group">
|
||||
@ -310,6 +320,12 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<input type="hidden"
|
||||
name="not_check_stock_fulfillment_for_recipes"
|
||||
id="not_check_stock_fulfillment_for_recipes"
|
||||
value="0">
|
||||
@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
|
||||
|
@ -118,6 +118,12 @@
|
||||
title="{{ $__t('Edit this item') }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-primary btn-sm"
|
||||
href="{{ $U('/product/new?copy-of=') }}{{ $product->id }}"
|
||||
data-toggle="tooltip"
|
||||
title="{{ $__t('Copy this item') }}">
|
||||
<i class="fas fa-copy"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger btn-sm product-delete-button @if($product->active == 0) disabled @endif"
|
||||
href="#"
|
||||
data-product-id="{{ $product->id }}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user