mirror of
https://github.com/grocy/grocy.git
synced 2026-04-04 11:56:16 +02:00
795 lines
47 KiB
PHP
795 lines
47 KiB
PHP
@extends('layout.default')
|
|
|
|
@if ($mode == 'edit')
|
|
@section('title', $__t('Edit product'))
|
|
@else
|
|
@section('title', $__t('Create product'))
|
|
@endif
|
|
|
|
@section('viewJsName', 'productform')
|
|
|
|
@section('content')
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="title-related-links">
|
|
<h2 class="title">@yield('title')</h2>
|
|
@if ($mode == 'edit')
|
|
<div class="float-right">
|
|
<button class="btn btn-outline-dark d-md-none mt-2 order-1 order-md-3" type="button"
|
|
data-toggle="collapse" data-target="#related-links">
|
|
<i class="fas fa-ellipsis-v"></i>
|
|
</button>
|
|
</div>
|
|
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" id="related-links">
|
|
<a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
|
|
href="{{ $U('/stockentries?embedded&product=') }}{{ $product->id }}">
|
|
{{ $__t('Stock entries') }}
|
|
</a>
|
|
<a class="btn btn-outline-secondary m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
|
|
href="{{ $U('/stockentries?embedded&product=') }}{{ $product->id }}">
|
|
{{ $__t('Stock journal') }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-2">
|
|
|
|
<div class="row">
|
|
<div class="col-lg-6 col-12">
|
|
<script>
|
|
Grocy.EditMode = '{{ $mode }}';
|
|
</script>
|
|
|
|
@if ($mode == 'edit')
|
|
<script>
|
|
Grocy.EditObjectId = {{ $product->id }};
|
|
</script>
|
|
|
|
@if (!empty($product->picture_file_name))
|
|
<script>
|
|
Grocy.ProductPictureFileName = '{{ $product->picture_file_name }}';
|
|
</script>
|
|
@endif
|
|
@endif
|
|
|
|
<form id="product-form" class="has-sticky-form-footer" novalidate>
|
|
|
|
<div class="form-group">
|
|
<label for="name">{{ $__t('Name') }}</label>
|
|
<input type="text" class="form-control" required id="name" name="name"
|
|
value="@if ($mode == 'edit') {{ $product->name }} @endif">
|
|
<div class="invalid-feedback">{{ $__t('A name is required') }}</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="custom-control custom-checkbox">
|
|
<input
|
|
@if ($mode == 'create') checked
|
|
@elseif($mode == 'edit' && $product->active == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox" id="active" name="active"
|
|
value="1">
|
|
<label class="form-check-label custom-control-label" for="active">{{ $__t('Active') }}</label>
|
|
</div>
|
|
</div>
|
|
|
|
@php
|
|
$prefillById = '';
|
|
if ($mode == 'edit') {
|
|
$prefillById = $product->parent_product_id;
|
|
}
|
|
@endphp
|
|
@php
|
|
$hint = '';
|
|
if ($isSubProductOfOthers) {
|
|
$hint = $__t('Not possible because this product is already used as a parent product in another product');
|
|
}
|
|
@endphp
|
|
@include('components.productpicker', [
|
|
'productsQuery' => (isset($product) ? 'query%5B%5D=id!%3D' . rawurlencode($product->id) . '&' : '') . 'query%5B%5D=parent_product_id%3Dnull&query%5B%5D=active%3D1&order=name%3Acollate%20nocase',
|
|
'prefillById' => $prefillById,
|
|
'disallowAllProductWorkflows' => true,
|
|
'isRequired' => false,
|
|
'label' => 'Parent product',
|
|
'disabled' => $isSubProductOfOthers,
|
|
'hint' => $hint,
|
|
])
|
|
@php $hint = ''; @endphp
|
|
|
|
<div class="form-group">
|
|
<label for="description">{{ $__t('Description') }}</label>
|
|
<textarea class="form-control wysiwyg-editor" id="description" name="description">
|
|
@if ($mode == 'edit')
|
|
{{ $product->description }}
|
|
@endif
|
|
</textarea>
|
|
</div>
|
|
|
|
@if (GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
|
<div class="form-group">
|
|
<label for="location_id">{{ $__t('Default location') }}</label>
|
|
{{-- TODO: Select2: dynamic data: locations --}}
|
|
<select required class="custom-control custom-select" id="location_id" name="location_id">
|
|
<option></option>
|
|
@foreach ($locations as $location)
|
|
<option @if ($mode == 'edit' && $location->id == $product->location_id) selected="selected" @endif
|
|
value="{{ $location->id }}">{{ $location->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
<div class="invalid-feedback">{{ $__t('A location is required') }}</div>
|
|
</div>
|
|
@else
|
|
<input type="hidden" name="location_id" id="location_id" value="1">
|
|
@endif
|
|
|
|
@php
|
|
$prefillById = '';
|
|
if ($mode == 'edit') {
|
|
$prefillById = $product->shopping_location_id;
|
|
}
|
|
@endphp
|
|
@if (GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
|
@include('components.shoppinglocationpicker', [
|
|
'label' => 'Default store',
|
|
'prefillById' => $prefillById,
|
|
'shoppinglocations' => $shoppinglocations,
|
|
])
|
|
@else
|
|
<input type="hidden" name="shopping_location_id" id="shopping_location_id" value="1">
|
|
@endif
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->min_stock_amount;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'min_stock_amount',
|
|
'label' => 'Minimum stock amount',
|
|
'min' => '0.',
|
|
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
|
'value' => $value,
|
|
'additionalGroupCssClasses' => 'mb-1',
|
|
'additionalCssClasses' => 'locale-number-input locale-number-quantity-amount',
|
|
])
|
|
|
|
<div class="form-group @if (GROCY_FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING) mb-1 @endif">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->cumulate_min_stock_amount_of_sub_products == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox"
|
|
id="cumulate_min_stock_amount_of_sub_products" name="cumulate_min_stock_amount_of_sub_products"
|
|
value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="cumulate_min_stock_amount_of_sub_products">{{ $__t('Accumulate sub products min. stock amount') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be missing, only this product') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
@if (GROCY_FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING)
|
|
<div class="form-group">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->treat_opened_as_out_of_stock == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox"
|
|
id="treat_opened_as_out_of_stock" name="treat_opened_as_out_of_stock" value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="treat_opened_as_out_of_stock">{{ $__t('Treat opened as out of stock') }} <i
|
|
class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('When enabled, opened items will be counted as missing for calculating if this product is below its minimum stock amount') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
@if (GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)
|
|
<div class="form-group">
|
|
<label class="d-block my-0" for="location_id">{{ $__t('Due date type') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('Based on the selected type, the highlighting on the stock overview page will be different') }}"></i>
|
|
</label>
|
|
<div class="custom-control custom-radio mt-n2">
|
|
<input class="custom-control-input" type="radio" name="due_type" id="due-type-bestbefore"
|
|
value="1" @if ($mode == 'edit' && $product->due_type == 1) checked @else checked @endif>
|
|
<label class="custom-control-label" for="due-type-bestbefore">{{ $__t('Best before date') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('Means that the product is maybe still safe to be consumed after its due date is reached') }}"></i>
|
|
</label>
|
|
</div>
|
|
<div class="custom-control custom-radio mt-n2">
|
|
<input class="custom-control-input" type="radio" name="due_type" id="due-type-expiration"
|
|
value="2" @if ($mode == 'edit' && $product->due_type == 2) checked @endif>
|
|
<label class="custom-control-label" for="due-type-expiration">{{ $__t('Expiration date') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('Means that the product is not safe to be consumed after its due date is reached') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->default_best_before_days;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'default_best_before_days',
|
|
'label' => 'Default due days',
|
|
'min' => -1,
|
|
'value' => $value,
|
|
'hint' =>
|
|
$__t(
|
|
'For purchases this amount of days will be added to today for the due date suggestion'
|
|
) .
|
|
' (' .
|
|
$__t('-1 means that this product will be never overdue') .
|
|
')',
|
|
])
|
|
|
|
@if (GROCY_FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING)
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->default_best_before_days_after_open;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'default_best_before_days_after_open',
|
|
'label' => 'Default due days after opened',
|
|
'min' => 0,
|
|
'value' => $value,
|
|
'hint' => $__t(
|
|
'When this product was marked as opened, the due date will be replaced by today + this amount of days, but only if the resulting date is not after the original due date (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">
|
|
<input type="hidden" name="due_type" id="due_type" value="1">
|
|
@endif
|
|
|
|
@if (GROCY_FEATURE_FLAG_STOCK_PRODUCT_FREEZING)
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->default_best_before_days_after_freezing;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'default_best_before_days_after_freezing',
|
|
'label' => 'Default due days after freezing',
|
|
'min' => -1,
|
|
'value' => $value,
|
|
'hint' =>
|
|
$__t(
|
|
'On moving this product to a freezer location (so when freezing it), the due date will be replaced by today + this amount of days'
|
|
) .
|
|
' (' .
|
|
$__t('-1 means that this product will be never overdue') .
|
|
')',
|
|
])
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->default_best_before_days_after_thawing;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'default_best_before_days_after_thawing',
|
|
'label' => 'Default due days after thawing',
|
|
'min' => 0,
|
|
'value' => $value,
|
|
'hint' => $__t(
|
|
'On moving this product from a freezer location (so when thawing it), the due date will be replaced by today + this amount of days'
|
|
),
|
|
])
|
|
|
|
<div class="form-group">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->should_not_be_frozen == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox" id="should_not_be_frozen"
|
|
name="should_not_be_frozen" value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="should_not_be_frozen">{{ $__t('Should not be frozen') }} <i
|
|
class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('When enabled, on moving this product to a freezer location (so when freezing it), a warning will be shown') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<input type="hidden" name="default_best_before_days_after_freezing" value="0">
|
|
<input type="hidden" name="default_best_before_days_after_thawing" value="0">
|
|
<input type="hidden" name="should_not_be_frozen" value="0">
|
|
@endif
|
|
|
|
<div class="form-group">
|
|
<label for="product_group_id">{{ $__t('Product group') }}</label>
|
|
{{-- TODO: Select2: dynamic data: product_groups --}}
|
|
<select class="custom-control custom-select" id="product_group_id" name="product_group_id">
|
|
<option></option>
|
|
@foreach ($productgroups as $productgroup)
|
|
<option @if ($mode == 'edit' && $productgroup->id == $product->product_group_id) selected="selected" @endif
|
|
value="{{ $productgroup->id }}">{{ $productgroup->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="qu_id_stock">{{ $__t('Quantity unit stock') }}</label>
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('Quantity unit stock cannot be changed after first purchase') }}"></i>
|
|
{{-- TODO: Select2: dynamic data: quantity_units --}}
|
|
<select required class="custom-control custom-select input-group-qu" id="qu_id_stock" name="qu_id_stock"
|
|
@if ($mode == 'edit') disabled @endif>
|
|
<option></option>
|
|
@foreach ($quantityunits as $quantityunit)
|
|
<option @if ($mode == 'edit' && $quantityunit->id == $product->qu_id_stock) selected="selected" @endif
|
|
value="{{ $quantityunit->id }}" data-plural-form="{{ $quantityunit->name_plural }}">
|
|
{{ $quantityunit->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
<div class="invalid-feedback">{{ $__t('A quantity unit is required') }}</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="qu_id_purchase">{{ $__t('Default quantity unit purchase') }}</label>
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('This is the default quantity unit used when adding this product to the shopping list') }}"></i>
|
|
{{-- TODO: Select2: dynamic data: quantity_units --}}
|
|
<select required class="custom-control custom-select input-group-qu" id="qu_id_purchase"
|
|
name="qu_id_purchase">
|
|
<option></option>
|
|
@foreach ($quantityunits as $quantityunit)
|
|
<option @if ($mode == 'edit' && $quantityunit->id == $product->qu_id_purchase) selected="selected" @endif
|
|
value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
<div class="invalid-feedback">{{ $__t('A quantity unit is required') }}</div>
|
|
</div>
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->qu_factor_purchase_to_stock;
|
|
} else {
|
|
$value = 1;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'qu_factor_purchase_to_stock',
|
|
'label' => 'Factor purchase to stock quantity unit',
|
|
'min' => $DEFAULT_MIN_AMOUNT,
|
|
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
|
'value' => $value,
|
|
'additionalCssClasses' => 'input-group-qu locale-number-input locale-number-quantity-amount',
|
|
'additionalHtmlElements' => '<p id="qu-conversion-info"
|
|
class="form-text text-info d-none"></p>',
|
|
])
|
|
|
|
<div class="form-group mb-1">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->enable_tare_weight_handling == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox" id="enable_tare_weight_handling"
|
|
name="enable_tare_weight_handling" value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="enable_tare_weight_handling">{{ $__t('Enable tare weight handling') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('This is useful e.g. for flour in jars - on purchase/consume/inventory you always weigh the whole jar, the amount to be posted is then automatically calculated based on what is in stock and the tare weight defined below') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->tare_weight;
|
|
} else {
|
|
$value = 0;
|
|
}
|
|
@endphp
|
|
@php
|
|
if (($mode == 'edit' && $product->enable_tare_weight_handling == 0) || $mode == 'create') {
|
|
$additionalAttributes = 'disabled';
|
|
} else {
|
|
$additionalAttributes = '';
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'tare_weight',
|
|
'label' => 'Tare weight',
|
|
'min' => 0,
|
|
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
|
'value' => $value,
|
|
'additionalAttributes' => $additionalAttributes,
|
|
'contextInfoId' => 'tare_weight_qu_info',
|
|
'additionalCssClasses' => 'locale-number-input locale-number-quantity-amount',
|
|
])
|
|
@php $additionalAttributes = '' @endphp
|
|
|
|
@if (GROCY_FEATURE_FLAG_RECIPES)
|
|
<div class="form-group">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->not_check_stock_fulfillment_for_recipes == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox"
|
|
id="not_check_stock_fulfillment_for_recipes" name="not_check_stock_fulfillment_for_recipes"
|
|
value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="not_check_stock_fulfillment_for_recipes">{{ $__t('Disable stock fulfillment checking for this ingredient') }}
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip"
|
|
data-trigger="hover click"
|
|
title="{{ $__t('This will be used as the default setting when adding this product as a recipe ingredient') }}"></i>
|
|
</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', [
|
|
'id' => 'calories',
|
|
'label' => 'Energy (kcal)',
|
|
'min' => '0.' . str_repeat('0', $userSettings['stock_decimal_places_amounts']),
|
|
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
|
'value' => $value,
|
|
'hint' => $__t('Per stock quantity unit'),
|
|
'contextInfoId' => 'energy_qu_info',
|
|
'isRequired' => false,
|
|
'additionalCssClasses' => 'locale-number-input locale-number-quantity-amount',
|
|
])
|
|
|
|
@php
|
|
if ($mode == 'edit') {
|
|
$value = $product->quick_consume_amount;
|
|
} else {
|
|
$value = 1;
|
|
}
|
|
@endphp
|
|
@include('components.numberpicker', [
|
|
'id' => 'quick_consume_amount',
|
|
'label' => 'Quick consume amount',
|
|
'min' => $DEFAULT_MIN_AMOUNT,
|
|
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
|
'value' => $value,
|
|
'hint' => $__t(
|
|
'This amount is used for the "quick consume/open buttons" on the stock overview page (related to quantity unit stock)'
|
|
),
|
|
'contextInfoId' => 'quick_consume_qu_info',
|
|
'additionalCssClasses' => 'locale-number-input locale-number-quantity-amount',
|
|
])
|
|
|
|
@if (GROCY_FEATURE_FLAG_LABEL_PRINTER)
|
|
<div class="form-group">
|
|
<label for="default_stock_label_type">{{ $__t('Default stock entry label') }}</label>
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('This is the default which will be prefilled on purchase') }}"></i>
|
|
<select class="form-control" id="default_stock_label_type" name="default_stock_label_type">
|
|
<option @if ($mode == 'edit' && intval($product->default_stock_label_type) == 0) selected="selected" @endif value="0">
|
|
{{ $__t('No label') }}</option>
|
|
<option @if ($mode == 'edit' && intval($product->default_stock_label_type) == 1) selected="selected" @endif value="1">
|
|
{{ $__t('Single label') }}</option>
|
|
<option @if ($mode == 'edit' && intval($product->default_stock_label_type) == 2) selected="selected" @endif value="2">
|
|
{{ $__t('Label per unit') }}</option>
|
|
</select>
|
|
</div>
|
|
@endif
|
|
|
|
@include('components.userfieldsform', [
|
|
'userfields' => $userfields,
|
|
'entity' => 'products',
|
|
])
|
|
|
|
<div class="form-group">
|
|
<div class="custom-control custom-checkbox">
|
|
<input @if ($mode == 'edit' && $product->hide_on_stock_overview == 1) checked @endif
|
|
class="form-check-input custom-control-input" type="checkbox" id="hide_on_stock_overview"
|
|
name="hide_on_stock_overview" value="1">
|
|
<label class="form-check-label custom-control-label"
|
|
for="hide_on_stock_overview">{{ $__t('Never show on stock overview') }} <i
|
|
class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('The stock overview page lists all products which are currently in-stock or below their min. stock amount - enable this to hide this product there always') }}"></i>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="sticky-form-footer pt-1">
|
|
<small id="save-hint"
|
|
class="my-1 form-text text-muted @if ($mode == 'edit') d-none @endif">{{ $__t('Save & continue to add quantity unit conversions & barcodes') }}</small>
|
|
|
|
<button id="save-product-button" class="save-product-button btn btn-success mb-2 default-submit-button"
|
|
data-location="continue">{{ $__t('Save & continue') }}</button>
|
|
<button class="save-product-button btn btn-info mb-2"
|
|
data-location="return">{{ $__t('Save & return to products') }}</button>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
|
|
<div class="col-lg-6 col-12">
|
|
|
|
<div class="row @if ($mode == 'create' || !GROCY_FEATURE_FLAG_STOCK) d-none @endif">
|
|
<div class="col">
|
|
<div class="title-related-links">
|
|
<h4>
|
|
{{ $__t('Barcodes') }}
|
|
</h4>
|
|
<button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3" type="button"
|
|
data-toggle="collapse" data-target="#related-links">
|
|
<i class="fas fa-ellipsis-v"></i>
|
|
</button>
|
|
@if ($mode == 'edit')
|
|
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" id="related-links">
|
|
<a class="btn btn-outline-primary btn-sm m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
|
|
href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id) }}">
|
|
{{ $__t('Add') }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<h5 id="barcode-headline-info" class="text-muted font-italic"></h5>
|
|
|
|
{{-- TODO: DataTables: dynamic data: barcodes --}}
|
|
<table id="barcode-table" class="table table-sm table-striped nowrap w-100">
|
|
<thead>
|
|
<tr>
|
|
<th class="border-right"><a class="text-muted change-table-columns-visibility-button"
|
|
data-toggle="tooltip" data-toggle="tooltip" title="{{ $__t('Table options') }}"
|
|
data-table-selector="#barcode-table" href="#"><i class="fas fa-eye"></i></a>
|
|
</th>
|
|
<th>{{ $__t('Barcode') }}</th>
|
|
<th class="@if (!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif allow-grouping">
|
|
{{ $__t('Store') }}</th>
|
|
<th class="allow-grouping">{{ $__t('Quantity unit') }}</th>
|
|
<th>{{ $__t('Amount') }}</th>
|
|
<th class="@if (!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">{{ $__t('Last price') }}
|
|
</th>
|
|
<th>{{ $__t('Note') }}</th>
|
|
|
|
@include('components.userfields_thead', [
|
|
'userfields' => $productBarcodeUserfields,
|
|
])
|
|
</tr>
|
|
</thead>
|
|
<tbody class="d-none">
|
|
@if ($mode == 'edit')
|
|
@foreach ($barcodes as $barcode)
|
|
@if ($barcode->product_id == $product->id || $barcode->product_id == null)
|
|
<tr>
|
|
<td class="fit-content border-right">
|
|
<a class="btn btn-sm btn-info show-as-dialog-link @if ($barcode->product_id == null) disabled @endif"
|
|
href="{{ $U('/productbarcodes/' . $barcode->id . '?embedded&product=' . $product->id) }}">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
<a class="btn btn-sm btn-danger barcode-delete-button @if ($barcode->product_id == null) disabled @endif"
|
|
href="#" data-barcode-id="{{ $barcode->id }}"
|
|
data-barcode="{{ $barcode->barcode }}"
|
|
data-product-barcode="{{ $product->barcode }}"
|
|
data-product-id="{{ $product->id }}">
|
|
<i class="fas fa-trash"></i>
|
|
</a>
|
|
</td>
|
|
<td>
|
|
{{ $barcode->barcode }}
|
|
</td>
|
|
<td class="@if (!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif"
|
|
id="barcode-shopping-location">
|
|
@if (FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id) !== null)
|
|
{{ FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id)->name }}
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@if (!empty($barcode->qu_id))
|
|
{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', $barcode->qu_id)->name }}
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@if (!empty($barcode->amount))
|
|
<span
|
|
class="locale-number locale-number-quantity-amount">{{ $barcode->amount }}</span>
|
|
@endif
|
|
</td>
|
|
<td class="@if (!GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING) d-none @endif">
|
|
<span
|
|
class="locale-number locale-number-currency">{{ $barcode->last_price }}</span>
|
|
</td>
|
|
<td>
|
|
{{ $barcode->note }}
|
|
</td>
|
|
|
|
@include('components.userfields_tbody', [
|
|
'userfields' => $productBarcodeUserfields,
|
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue(
|
|
$productBarcodeUserfieldValues,
|
|
'object_id',
|
|
$barcode->id
|
|
),
|
|
])
|
|
</tr>
|
|
@endif
|
|
@endforeach
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-2 @if ($mode == 'create') d-none @endif">
|
|
<div class="col clearfix">
|
|
<div class="title-related-links">
|
|
<h4>
|
|
<span class="ls-n1">{{ $__t('grocycode') }}</span>
|
|
<i class="fas fa-question-circle text-muted" data-toggle="tooltip" data-trigger="hover click"
|
|
title="{{ $__t('grocycode is a unique referer to this %s in your grocy instance - print it onto a label and scan it like any other barcode',$__t('Product')) }}"></i>
|
|
</h4>
|
|
<p>
|
|
@if ($mode == 'edit')
|
|
<img src="{{ $U('/product/' . $product->id . '/grocycode?size=60') }}"
|
|
class="float-lg-left">
|
|
@endif
|
|
</p>
|
|
<p>
|
|
<a class="btn btn-outline-primary btn-sm"
|
|
href="{{ $U('/product/' . $product->id . '/grocycode?download=true') }}">{{ $__t('Download') }}</a>
|
|
@if (GROCY_FEATURE_FLAG_LABEL_PRINTER)
|
|
<a class="btn btn-outline-primary btn-sm product-grocycode-label-print"
|
|
data-product-id="{{ $product->id }}" href="#">
|
|
{{ $__t('Print on label printer') }}
|
|
</a>
|
|
@endif
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="row @if (GROCY_FEATURE_FLAG_STOCK) mt-5 @endif @if ($mode == 'create') d-none @endif">
|
|
<div class="col">
|
|
<div class="title-related-links">
|
|
<h4>
|
|
{{ $__t('QU conversions') }}
|
|
</h4>
|
|
<button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3" type="button"
|
|
data-toggle="collapse" data-target="#related-links">
|
|
<i class="fas fa-ellipsis-v"></i>
|
|
</button>
|
|
@if ($mode == 'edit')
|
|
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100" id="related-links">
|
|
<a class="btn btn-outline-primary btn-sm m-1 mt-md-0 mb-md-0 float-right show-as-dialog-link"
|
|
href="{{ $U('/quantityunitconversion/new?embedded&product=' . $product->id) }}">
|
|
{{ $__t('Add') }}
|
|
</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<h5 id="qu-conversion-headline-info" class="text-muted font-italic"></h5>
|
|
|
|
{{-- TODO: DataTables: dynamic data: quantity_unit_conversions --}}
|
|
<table id="qu-conversions-table-products" class="table table-sm table-striped nowrap w-100">
|
|
<thead>
|
|
<tr>
|
|
<th class="border-right"><a class="text-muted change-table-columns-visibility-button"
|
|
data-toggle="tooltip" title="{{ $__t('Table options') }}"
|
|
data-table-selector="#qu-conversions-table-products" href="#"><i
|
|
class="fas fa-eye"></i></a>
|
|
</th>
|
|
<th class="allow-grouping">{{ $__t('Quantity unit from') }}</th>
|
|
<th class="allow-grouping">{{ $__t('Quantity unit to') }}</th>
|
|
<th>{{ $__t('Factor') }}</th>
|
|
<th class="allow-grouping">{{ $__t('Group') }}</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="d-none">
|
|
@if ($mode == 'edit')
|
|
@foreach ($quConversions as $quConversion)
|
|
@if ($quConversion->product_id == $product->id || ($quConversion->product_id == null && ($quConversion->product_id != null || $quConversion->from_qu_id == $product->qu_id_purchase || $quConversion->from_qu_id == $product->qu_id_stock || $quConversion->to_qu_id == $product->qu_id_purchase || $quConversion->to_qu_id == $product->qu_id_stock)))
|
|
<tr>
|
|
<td class="fit-content border-right">
|
|
<a class="btn btn-sm btn-info show-as-dialog-link @if ($quConversion->product_id == null) disabled @endif"
|
|
href="{{ $U('/quantityunitconversion/' . $quConversion->id . '?embedded&product=' . $product->id) }}">
|
|
<i class="fas fa-edit"></i>
|
|
</a>
|
|
<a class="btn btn-sm btn-danger qu-conversion-delete-button @if ($quConversion->product_id == null) disabled @endif"
|
|
href="#" data-qu-conversion-id="{{ $quConversion->id }}">
|
|
<i class="fas fa-trash"></i>
|
|
</a>
|
|
</td>
|
|
<td>
|
|
{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->from_qu_id)->name }}
|
|
</td>
|
|
<td>
|
|
{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name }}
|
|
</td>
|
|
<td>
|
|
<span
|
|
class="locale-number locale-number-quantity-amount">{{ $quConversion->factor }}</span>
|
|
</td>
|
|
<td class="d-none">
|
|
@if ($quConversion->product_id != null)
|
|
{{ $__t('Product overrides') }}
|
|
@else
|
|
{{ $__t('Default conversions') }}
|
|
@endif
|
|
</td>
|
|
<td class="font-italic">
|
|
{!! $__t('This means 1 %1$s is the same as %2$s %3$s', FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->from_qu_id)->name, '<span class="locale-number locale-number-quantity-amount">' . $quConversion->factor . '</span>', $__n($quConversion->factor, FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name_plural, true)) !!}
|
|
</td>
|
|
</tr>
|
|
@endif
|
|
@endforeach
|
|
@endif
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row @if ($mode == 'edit') mt-5 @endif">
|
|
<div class="col">
|
|
<div class="title-related-links">
|
|
<h4>
|
|
{{ $__t('Picture') }}
|
|
</h4>
|
|
<div class="form-group w-75 m-0">
|
|
<div class="input-group">
|
|
<div class="custom-file">
|
|
<input type="file" class="custom-file-input" id="product-picture" accept="image/*">
|
|
<label id="product-picture-label"
|
|
class="custom-file-label @if (empty($product->picture_file_name)) d-none @endif"
|
|
for="product-picture">
|
|
{{ $product->picture_file_name }}
|
|
</label>
|
|
<label id="product-picture-label-none"
|
|
class="custom-file-label @if (!empty($product->picture_file_name)) d-none @endif"
|
|
for="product-picture">
|
|
{{ $__t('No file selected') }}
|
|
</label>
|
|
</div>
|
|
<div class="input-group-append">
|
|
<span class="input-group-text"><i class="fas fa-trash"
|
|
id="delete-current-product-picture-button"></i></span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@if ($mode == 'edit' && !empty($product->picture_file_name))
|
|
<img id="current-product-picture"
|
|
data-src="{{ $U('/api/files/productpictures/' .base64_encode($product->picture_file_name) .'?force_serve_as=picture&best_fit_width=400') }}"
|
|
class="img-fluid img-thumbnail mt-2 lazy mb-5">
|
|
<p id="delete-current-product-picture-on-save-hint"
|
|
class="form-text text-muted font-italic d-none mb-5">
|
|
{{ $__t('The current picture will be deleted on save') }}</p>
|
|
@else
|
|
<p id="no-current-product-picture-hint" class="form-text text-muted font-italic mb-5">
|
|
{{ $__t('No picture available') }}</p>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@stop
|