mirror of
https://github.com/grocy/grocy.git
synced 2025-10-15 01:37:13 +00:00
Qu factor purchase to stock & Product Barcode Details (#801)
* Puchase add qu_factor_to_stock * qu_factor_purchase_to_stock for stock edit * product barcodes with QU and Stores * remove product barcode tags * migrations/0103 add value and factor_puchase_amount to stock_current and stock_current_location_content * Remove unused method * StockService#GetProductDetails: include stock_value * productcard: include stock_value * Add Purchase Factor to Stock Overview * update demo data with stock qu_factor_purchase_to_stock * recipes_pos_resolved update * avg_price and oldest_price in product details * add average price to product card * hint for recipe costs not included if not in stock * Round value and factor_purchas_amount. Include currency for stock value * Add factor_purchase_amount to product card stock amount * Allow editing qu_factor_purchase_to_stock for stock entries * fix update qu_factor_purchase_to_stock for Transfers * Add barcode to existing product update to add to product_barcodes table * Add barcode to new product workflow update to add to product_barcodes table * *** Price now saved as 1 QU to stock in stock tables *** * remove column product barcode and use product_barcodes * Allow products to be deactivated instead of deleted * Embedded barcode and qu-conversion with page reload on change * Save current product barcode into new product_barcodes table * Embedded popup for product group add/edit * barcode scanner added to product barcodes input * Edit product qu_stock is unavailable after first purchase * StockOverview: Filters break when columns are reordered so for now just disable colReorder * view stockoverview.blade: display product_group column * Review Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
@php if(!isset($isRequired)) { $isRequired = true; } @endphp
|
||||
@php if(!isset($noNameAttribute)) { $noNameAttribute = false; } @endphp
|
||||
|
||||
<div class="form-group {{ $additionalGroupCssClasses }}">
|
||||
<div id="group-{{ $id }}" class="form-group {{ $additionalGroupCssClasses }}">
|
||||
<label for="{{ $id }}">
|
||||
{{ $__t($label) }}
|
||||
<i class="fas fa-question-circle" id="{{ $hintId }}" data-toggle="tooltip" title="{{ $hint }}"></i>{!! $additionalHtmlContextHelp !!}</label>
|
||||
|
@@ -21,12 +21,16 @@
|
||||
<a class="collapsed" data-toggle="collapse" href="#productcard-product-description">{{ $__t('Show more') }}</a>
|
||||
</div>
|
||||
|
||||
<strong>{{ $__t('Stock amount') . ' / ' . $__t('Quantity unit') }}:</strong> <span id="productcard-product-stock-amount" class="locale-number locale-number-quantity-amount"></span> <span id="productcard-product-stock-qu-name"></span> <span id="productcard-product-stock-opened-amount" class="small font-italic locale-number locale-number-quantity-amount"></span>
|
||||
<strong>{{ $__t('Stock amount') }}:</strong> <span id="productcard-product-stock-amount" class="locale-number locale-number-quantity-amount"></span> <span id="productcard-product-stock-qu-name"></span>
|
||||
<span id="productcard-product-stock-factor-purchase-amount" class="locale-number locale-number-quantity-amount"></span> <span id="productcard-product-stock-factor-purchase-qu-name"></span>
|
||||
<span id="productcard-product-stock-opened-amount" class="small font-italic locale-number locale-number-quantity-amount"></span><br>
|
||||
<strong>{{ $__t('Stock value') }}:</strong> <span id="productcard-product-stock-value" class="locale-number locale-number-currency"></span>
|
||||
<span id="productcard-aggregated-amounts" class="pl-2 text-secondary d-none"><i class="fas fa-custom-sigma-sign"></i> <span id="productcard-product-stock-amount-aggregated" class="locale-number locale-number-quantity-amount"></span> <span id="productcard-product-stock-qu-name-aggregated"></span> <span id="productcard-product-stock-opened-amount-aggregated locale-number locale-number-quantity-amount" class="small font-italic"></span></span><br>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)<strong>{{ $__t('Default location') }}:</strong> <span id="productcard-product-location"></span><br>@endif
|
||||
<strong>{{ $__t('Last purchased') }}:</strong> <span id="productcard-product-last-purchased"></span> <time id="productcard-product-last-purchased-timeago" class="timeago timeago-contextual"></time><br>
|
||||
<strong>{{ $__t('Last used') }}:</strong> <span id="productcard-product-last-used"></span> <time id="productcard-product-last-used-timeago" class="timeago timeago-contextual"></time><br>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>{{ $__t('Last price') }}:</strong> <span id="productcard-product-last-price"></span><br>@endif
|
||||
@if (GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)<strong>{{ $__t('Average price') }}:</strong> <span id="productcard-product-average-price"></span><br>@endif
|
||||
@if (GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)<strong>{{ $__t('Average shelf life') }}:</strong> <span id="productcard-product-average-shelf-life"></span><br>@endif
|
||||
<strong>{{ $__t('Spoil rate') }}:</strong> <span id="productcard-product-spoil-rate"></span>
|
||||
|
||||
|
@@ -21,7 +21,7 @@
|
||||
<select class="form-control product-combobox barcodescanner-input" id="product_id" name="product_id" @if($isRequired) required @endif @if($disabled) disabled @endif data-target="@productpicker">
|
||||
<option value=""></option>
|
||||
@foreach($products as $product)
|
||||
<option data-additional-searchdata="{{ $product->barcode }}@if(!empty($product->barcode)),@endif" value="{{ $product->id }}">{{ $product->name }}</option>
|
||||
<option data-additional-searchdata="{{ FindObjectInArrayByPropertyValue($barcodes, 'product_id', $product->id)->barcodes }}," value="{{ $product->id }}">{{ $product->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="invalid-feedback">{{ $__t('You have to select a product') }}</div>
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'barcodes' => $barcodes,
|
||||
'nextInputSelector' => '#amount',
|
||||
'disallowAddProductWorkflows' => true
|
||||
))
|
||||
|
@@ -13,6 +13,7 @@
|
||||
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'barcodes' => $barcodes,
|
||||
'nextInputSelector' => '#new_amount'
|
||||
))
|
||||
|
||||
|
71
views/productbarcodesform.blade.php
Normal file
71
views/productbarcodesform.blade.php
Normal file
@@ -0,0 +1,71 @@
|
||||
@extends('layout.default')
|
||||
|
||||
@if($mode == 'edit')
|
||||
@section('title', $__t('Edit Barcode'))
|
||||
@else
|
||||
@section('title', $__t('Create Barcode'))
|
||||
@endif
|
||||
|
||||
@section('viewJsName', 'productbarcodesform')
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2 class="title">@yield('title')</h2>
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-xs-12">
|
||||
|
||||
<h3 class="text-muted">{{ $__t('Barcode for product') }} <strong>{{ $product->name }}</strong></h3>
|
||||
|
||||
<script>Grocy.EditMode = '{{ $mode }}';</script>
|
||||
|
||||
@if($mode == 'edit')
|
||||
<script>Grocy.EditObjectId = {{ $barcode->id }};</script>
|
||||
@endif
|
||||
|
||||
<form id="barcode-form" novalidate>
|
||||
|
||||
<input type="hidden" name="product_id" value="{{ $product->id }}">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">{{ $__t('Barcode') }}<i class="fas fa-barcode"></i></label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control barcodescanner-input" required id="barcode" name="barcode" value="@if($mode == 'edit'){{ $barcode->barcode }}@endif" data-target="#scanned_barcode">
|
||||
@include('components.barcodescanner')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php if($mode == 'edit') { $value = $barcode->qu_factor_purchase_to_stock; } else { $value = 1; } @endphp
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'qu_factor_purchase_to_stock',
|
||||
'label' => 'Factor purchase to stock quantity unit',
|
||||
'min' => 1,
|
||||
'value' => $value,
|
||||
'isRequired' => true,
|
||||
'invalidFeedback' => $__t('The amount cannot be lower than %s', '1'),
|
||||
'additionalCssClasses' => 'input-group-qu',
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<div class="form-group">
|
||||
<label for="shopping_location_id_id">{{ $__t('Default store') }}</label>
|
||||
<select class="form-control" id="shopping_location_id" name="shopping_location_id">
|
||||
<option></option>
|
||||
@foreach($shoppinglocations as $store)
|
||||
<option @if($mode == 'edit' && $store->id == $product->shopping_location_id) selected="selected" @endif value="{{ $store->id }}">{{ $store->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@else
|
||||
<input type="hidden" name="shopping_location_id" id="shopping_location_id" value="1">
|
||||
@endif
|
||||
|
||||
<button id="save-barcode-button" class="btn btn-success">{{ $__t('Save') }}</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
@@ -46,6 +46,14 @@
|
||||
<div class="invalid-feedback">{{ $__t('A name is required') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="form-check">
|
||||
<input type="hidden" name="active" value="1">
|
||||
<input @if($mode == 'create') checked @elseif($mode == 'edit' && $product->active == 1) checked @endif class="form-check-input" type="checkbox" id="active" name="active" value="1">
|
||||
<label class="form-check-label" for="active">{{ $__t('Active') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php $prefillById = ''; if($mode=='edit') { $prefillById = $product->parent_product_id; } @endphp
|
||||
@php
|
||||
$hint = '';
|
||||
@@ -56,7 +64,6 @@
|
||||
@endphp
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'nextInputSelector' => '#barcode-taginput',
|
||||
'prefillById' => $prefillById,
|
||||
'disallowAllProductWorkflows' => true,
|
||||
'isRequired' => false,
|
||||
@@ -70,14 +77,6 @@
|
||||
<textarea class="form-control wysiwyg-editor" id="description" name="description">@if($mode == 'edit'){{ $product->description }}@endif</textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-group tm-group">
|
||||
<label for="barcode-taginput">{{ $__t('Barcode(s)') }} <i class="fas fa-barcode"></i></label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control tm-input barcodescanner-input" id="barcode-taginput" data-target="#barcode-taginput">
|
||||
</div>
|
||||
<div id="barcode-taginput-container"></div>
|
||||
</div>
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
||||
<div class="form-group">
|
||||
<label for="location_id">{{ $__t('Default location') }}</label>
|
||||
@@ -171,7 +170,8 @@
|
||||
|
||||
<div class="form-group">
|
||||
<label for="qu_id_stock">{{ $__t('Quantity unit stock') }}</label>
|
||||
<select required class="form-control input-group-qu" id="qu_id_stock" name="qu_id_stock">
|
||||
<i class="fas fa-question-circle" data-toggle="tooltip" title="Quantity unit stock cannot be changed after first purchase"></i>
|
||||
<select required class="form-control 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>
|
||||
@@ -295,7 +295,7 @@
|
||||
<div class="col-lg-6 col-xs-12">
|
||||
<h2>
|
||||
{{ $__t('QU conversions') }}
|
||||
<a id="qu-conversion-add-button" class="btn btn-outline-dark" href="#">
|
||||
<a class="btn btn-outline-dark show-as-dialog-link" type="button" href="{{ $U('/quantityunitconversion/new?embedded&product=' . $product->id ) }}">
|
||||
<i class="fas fa-plus"></i> {{ $__t('Add') }}
|
||||
</a>
|
||||
</h2>
|
||||
@@ -316,7 +316,7 @@
|
||||
@if($quConversion->product_id == $product->id || $quConversion->product_id == null)
|
||||
<tr>
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-sm btn-info qu-conversion-edit-button @if($quConversion->product_id == null) disabled @endif" href="#" data-qu-conversion-id="{{ $quConversion->id }}">
|
||||
<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 }}">
|
||||
@@ -346,6 +346,55 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>
|
||||
{{ $__t('Barcodes') }}
|
||||
<a class="btn btn-outline-dark show-as-dialog-link" type="button" href="{{ $U('/productbarcodes/new?embedded&product=' . $product->id ) }}">
|
||||
<i class="fas fa-plus"></i> {{ $__t('Add') }}
|
||||
</a>
|
||||
</h2>
|
||||
<h5 id="barcode-headline-info" class="text-muted font-italic"></h5>
|
||||
<table id="barcode-table" class="table table-sm table-striped dt-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="border-right"></th>
|
||||
<th>{{ $__t('Barcode') }}</th>
|
||||
<th>{{ $__t('Factor purchase to stock quantity unit') }}</th>
|
||||
<th>{{ $__t('Store') }}</th>
|
||||
</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>
|
||||
<span class="locale-number locale-number-quantity-amount">{{ $barcode->qu_factor_purchase_to_stock }}</span>
|
||||
</td>
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<td id="barcode-shopping-location">
|
||||
@if (FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id) !== null)
|
||||
{{ FindObjectInArrayByPropertyValue($shoppinglocations, 'id', $barcode->shopping_location_id)->name }}
|
||||
@endif
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="pt-5">
|
||||
<label class="mt-2">{{ $__t('Picture') }}</label>
|
||||
<button id="delete-current-product-picture-button" class="btn btn-sm btn-danger @if(empty($product->picture_file_name)) disabled @endif"><i class="fas fa-trash"></i> {{ $__t('Delete') }}</button>
|
||||
|
@@ -20,7 +20,7 @@
|
||||
<hr>
|
||||
<div class="row mt-3">
|
||||
<div class="col-xs-12 col-md-2 col-xl-1">
|
||||
<a class="btn btn-primary btn-sm responsive-button w-100 mb-3" href="{{ $U('/productgroup/new') }}">
|
||||
<a class="btn btn-primary btn-sm responsive-button w-100 mb-3 show-as-dialog-link" href="{{ $U('/productgroup/new?embedded') }}">
|
||||
{{ $__t('Add') }}
|
||||
</a>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
@foreach($productGroups as $productGroup)
|
||||
<tr>
|
||||
<td class="fit-content border-right">
|
||||
<a class="btn btn-info btn-sm" href="{{ $U('/productgroup/') }}{{ $productGroup->id }}">
|
||||
<a class="btn btn-info btn-sm show-as-dialog-link" href="{{ $U('/productgroup/') }}{{ $productGroup->id }}?embedded">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger btn-sm product-group-delete-button" href="#" data-group-id="{{ $productGroup->id }}" data-group-name="{{ $productGroup->name }}">
|
||||
|
@@ -81,12 +81,12 @@
|
||||
<a class="btn btn-info btn-sm" href="{{ $U('/product/') }}{{ $product->id }}">
|
||||
<i class="fas fa-edit"></i>
|
||||
</a>
|
||||
<a class="btn btn-danger btn-sm product-delete-button" href="#" data-product-id="{{ $product->id }}" data-product-name="{{ $product->name }}">
|
||||
<a class="btn btn-danger btn-sm product-delete-button @if($product->active == 0) disabled @endif" href="#" data-product-id="{{ $product->id }}" data-product-name="{{ $product->name }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ $product->name }}@if(!empty($product->picture_file_name)) <i class="fas fa-image text-muted"></i>@endif
|
||||
@if($product->active == 0) (deactivated) @endif {{ $product->name }}@if(!empty($product->picture_file_name)) <i class="fas fa-image text-muted"></i>@endif
|
||||
</td>
|
||||
<td class="@if(!GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING) d-none @endif">
|
||||
{{ FindObjectInArrayByPropertyValue($locations, 'id', $product->location_id)->name }}
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'barcodes' => $barcodes,
|
||||
'nextInputSelector' => '#amount'
|
||||
))
|
||||
|
||||
@@ -96,6 +97,16 @@
|
||||
<input type="hidden" name="price" id="price" value="0">
|
||||
@endif
|
||||
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'qu_factor_purchase_to_stock',
|
||||
'label' => 'Factor purchase to stock quantity unit',
|
||||
'min' => 1,
|
||||
'additionalGroupCssClasses' => 'd-none',
|
||||
'invalidFeedback' => $__t('The amount cannot be lower than %s', '1'),
|
||||
'additionalCssClasses' => 'input-group-qu',
|
||||
'additionalHtmlElements' => '<p id="qu-conversion-info" class="form-text text-muted small d-none"></p>'
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
|
||||
@include('components.locationpicker', array(
|
||||
'locations' => $locations,
|
||||
|
@@ -134,7 +134,7 @@
|
||||
<h5 class="card-title mb-1">{{ $recipe->name }}</h5>
|
||||
<p class="card-text">
|
||||
@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $__t('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $__n(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count, 'Not enough in stock, %s ingredient missing but already on the shopping list', 'Not enough in stock, %s ingredients missing but already on the shopping list') }}@else{{ $__n(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count, 'Not enough in stock, %s ingredient missing', 'Not enough in stock, %s ingredients missing') }}@endif</span>
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled == 1){{ $__t('Enough in stock') }}@elseif(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->need_fulfilled_with_shopping_list == 1){{ $__n(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count, 'Not enough in stock, %s ingredient missing but already on the shopping list', 'Not enough in stock, %s ingredients missing but already on the shopping list') }}@else{{ $__n(FindObjectInArrayByPropertyValue($recipesResolved, 'recipe_id', $recipe->id)->missing_products_count, 'Not enough in stock (not included in costs), %s ingredient missing', 'Not enough in stock (not included in costs), %s ingredients missing') }}@endif</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -250,7 +250,7 @@
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
<div class="col-5">
|
||||
<label>{{ $__t('Costs') }} </label>
|
||||
<i class="fas fa-question-circle" data-toggle="tooltip" title="{{ $__t('Based on the prices of the last purchase per product') }}"></i>
|
||||
<i class="fas fa-question-circle" data-toggle="tooltip" title="{{ $__t('Based on the prices of the default consume rule which is "First expiring first, then first in first out"') }}"></i>
|
||||
<h3 class="locale-number locale-number-currency pt-0">{{ $costs }}</h3>
|
||||
</div>
|
||||
@endif
|
||||
@@ -310,6 +310,9 @@
|
||||
<h6 class="mb-2 mt-2 @if($hasIngredientGroups) ml-3 @else ml-1 @endif"><strong>{{ $selectedRecipePosition->product_group }}</strong></h6>
|
||||
@endif
|
||||
<li class="list-group-item px-0 @if($hasIngredientGroups && $hasProductGroups) ml-4 @elseif($hasIngredientGroups || $hasProductGroups) ml-2 @else ml-0 @endif">
|
||||
@if($selectedRecipePosition->product_active == 0)
|
||||
<div class="small text-muted font-italic">{{ $__t('Deactivated Product') }}</div>
|
||||
@endif
|
||||
@php
|
||||
$product = FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id);
|
||||
$productQuConversions = FindAllObjectsInArrayByPropertyValue($quantityUnitConversionsResolved, 'product_id', $product->id);
|
||||
@@ -327,7 +330,7 @@
|
||||
@endif
|
||||
{{ $__n($selectedRecipePosition->recipe_amount, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name, FindObjectInArrayByPropertyValue($quantityUnits, 'id', $selectedRecipePosition->qu_id)->name_plural) }} {{ FindObjectInArrayByPropertyValue($products, 'id', $selectedRecipePosition->product_id)->name }}
|
||||
@if($selectedRecipePosition->need_fulfilled == 1)<i class="fas fa-check text-success"></i>@elseif($selectedRecipePosition->need_fulfilled_with_shopping_list == 1)<i class="fas fa-exclamation text-warning"></i>@else<i class="fas fa-times text-danger"></i>@endif
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $__t('Enough in stock') }} @else {{ $__t('Not enough in stock, %1$s missing, %2$s already on shopping list', round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, 2), round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list, 2)) }} @endif</span>
|
||||
<span class="timeago-contextual">@if(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->need_fulfilled == 1) {{ $__t('Enough in stock') }} @else {{ $__t('Not enough in stock (not included in costs), %1$s missing, %2$s already on shopping list', round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->missing_amount, 2), round(FindObjectInArrayByPropertyValue($recipePositionsResolved, 'recipe_pos_id', $selectedRecipePosition->id)->amount_on_shopping_list, 2)) }} @endif</span>
|
||||
|
||||
@if(!empty($selectedRecipePosition->recipe_variable_amount))
|
||||
<div class="small text-muted font-italic">{{ $__t('Variable amount') }}</div>
|
||||
|
@@ -41,6 +41,7 @@
|
||||
<th>{{ $__t('Store') }}</th>
|
||||
<th>{{ $__t('Price') }}</th>
|
||||
@endif
|
||||
<th>{{ $__t('Factor purchase to stock') }}</th>
|
||||
<th>{{ $__t('Purchased date') }}</th>
|
||||
|
||||
@include('components.userfields_thead', array(
|
||||
@@ -158,6 +159,9 @@
|
||||
{{ $stockEntry->price }}
|
||||
</td>
|
||||
@endif
|
||||
<td id="stock-{{ $stockEntry->id }}-qu-factor-purchase-to-stock">
|
||||
{{ $stockEntry->qu_factor_purchase_to_stock }}
|
||||
</td>
|
||||
<td>
|
||||
<span id="stock-{{ $stockEntry->id }}-purchased-date">{{ $stockEntry->purchased_date }}</span>
|
||||
<time id="stock-{{ $stockEntry->id }}-purchased-date-timeago" class="timeago timeago-contextual" datetime="{{ $stockEntry->purchased_date }} 23:59:59"></time>
|
||||
|
@@ -60,6 +60,16 @@
|
||||
'additionalHtmlContextHelp' => '<div id="tare-weight-handling-info" class="text-small text-info font-italic d-none">' . $__t('Tare weight handling enabled - please weigh the whole container, the amount to be posted will be automatically calculcated') . '</div>'
|
||||
))
|
||||
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'qu_factor_purchase_to_stock',
|
||||
'label' => 'Factor purchase to stock quantity unit',
|
||||
'value' => $stockEntry->qu_factor_purchase_to_stock,
|
||||
'min' => 1,
|
||||
'invalidFeedback' => $__t('The amount cannot be lower than %s', '1'),
|
||||
'additionalCssClasses' => 'input-group-qu',
|
||||
'additionalHtmlElements' => '<p id="qu-conversion-info" class="form-text text-muted small d-none"></p>'
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
|
||||
@include('components.numberpicker', array(
|
||||
'id' => 'price',
|
||||
|
@@ -104,11 +104,11 @@
|
||||
<tr>
|
||||
<th class="border-right"></th>
|
||||
<th>{{ $__t('Product') }}</th>
|
||||
<th>{{ $__t('Product group') }}</th>
|
||||
<th>{{ $__t('Amount') }}</th>
|
||||
<th class="@if(!GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING) d-none @endif">{{ $__t('Next best before date') }}</th>
|
||||
<th class="d-none">Hidden location</th>
|
||||
<th class="d-none">Hidden status</th>
|
||||
<th class="d-none">Hidden product group</th>
|
||||
|
||||
@include('components.userfields_thead', array(
|
||||
'userfields' => $userfields
|
||||
@@ -206,9 +206,16 @@
|
||||
<td class="product-name-cell cursor-link" data-product-id="{{ $currentStockEntry->product_id }}">
|
||||
{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}
|
||||
</td>
|
||||
@php $productGroup = FindObjectInArrayByPropertyValue($productGroups, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->product_group_id) @endphp
|
||||
<td>
|
||||
@if($productGroup !== null){{ $productGroup->name }}@endif
|
||||
</td>
|
||||
<td>
|
||||
<span id="product-{{ $currentStockEntry->product_id }}-amount" class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->amount }}</span> <span id="product-{{ $currentStockEntry->product_id }}-qu-name">{{ $__n($currentStockEntry->amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name_plural) }}</span>
|
||||
<span id="product-{{ $currentStockEntry->product_id }}-opened-amount" class="small font-italic">@if($currentStockEntry->amount_opened > 0){{ $__t('%s opened', $currentStockEntry->amount_opened) }}@endif</span>
|
||||
@if($currentStockEntry->amount != $currentStockEntry->factor_purchase_amount)
|
||||
<span id="product-{{ $currentStockEntry->product_id }}-factor-purchase-amount" class="locale-number locale-number-quantity-amount">({{ $currentStockEntry->factor_purchase_amount }}</span> <span id="product-{{ $currentStockEntry->product_id }}-qu-purchase-name">{{ $__n($currentStockEntry->factor_purchase_amount, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_purchase)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_purchase)->name_plural) }})</span>
|
||||
@endif
|
||||
@if($currentStockEntry->is_aggregated_amount == 1)
|
||||
<span class="pl-1 text-secondary">
|
||||
<i class="fas fa-custom-sigma-sign"></i> <span id="product-{{ $currentStockEntry->product_id }}-amount-aggregated" class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->amount_aggregated }}</span> {{ $__n($currentStockEntry->amount_aggregated, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name_plural) }}
|
||||
@@ -236,10 +243,6 @@
|
||||
<td class="d-none">
|
||||
@if($currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $currentStockEntry->amount > 0) expired @elseif($currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("+$nextXDays days")) && $currentStockEntry->amount > 0) expiring @endif @if(FindObjectInArrayByPropertyValue($missingProducts, 'id', $currentStockEntry->product_id) !== null) belowminstockamount @endif
|
||||
</td>
|
||||
@php $productGroup = FindObjectInArrayByPropertyValue($productGroups, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->product_group_id) @endphp
|
||||
<td class="d-none">
|
||||
@if($productGroup !== null){{ $productGroup->name }}@endif
|
||||
</td>
|
||||
|
||||
@include('components.userfields_tbody', array(
|
||||
'userfields' => $userfields,
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
@include('components.productpicker', array(
|
||||
'products' => $products,
|
||||
'barcodes' => $barcodes,
|
||||
'nextInputSelector' => '#location_id_from',
|
||||
'disallowAddProductWorkflows' => true
|
||||
))
|
||||
|
Reference in New Issue
Block a user