set default store for product, purchase set last store purchased if available or use product default (#672)

This commit is contained in:
kriddles 2020-03-27 13:27:40 -05:00 committed by GitHub
parent d509f9add0
commit 2fee4b45ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 39 additions and 6 deletions

View File

@ -179,6 +179,7 @@ class StockController extends BaseController
return $this->renderPage($response, 'productform', [ return $this->renderPage($response, 'productform', [
'locations' => $this->getDatabase()->locations()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name'),
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'), 'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'), 'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
'userfields' => $this->getUserfieldsService()->GetFields('products'), 'userfields' => $this->getUserfieldsService()->GetFields('products'),
'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL')->orderBy('name'), 'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL')->orderBy('name'),
@ -194,6 +195,7 @@ class StockController extends BaseController
'product' => $product, 'product' => $product,
'locations' => $this->getDatabase()->locations()->orderBy('name'), 'locations' => $this->getDatabase()->locations()->orderBy('name'),
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'), 'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'), 'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
'userfields' => $this->getUserfieldsService()->GetFields('products'), 'userfields' => $this->getUserfieldsService()->GetFields('products'),
'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL', $product->id)->orderBy('name'), 'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL', $product->id)->orderBy('name'),

View File

@ -3435,6 +3435,9 @@
"row_created_timestamp": { "row_created_timestamp": {
"type": "string", "type": "string",
"format": "date-time" "format": "date-time"
},
"shopping_location_id": {
"type": "integer"
} }
}, },
"example": { "example": {
@ -3455,7 +3458,8 @@
"allow_partial_units_in_stock": "0", "allow_partial_units_in_stock": "0",
"enable_tare_weight_handling": "0", "enable_tare_weight_handling": "0",
"tare_weight": "0.0", "tare_weight": "0.0",
"not_check_stock_fulfillment_for_recipes": "0" "not_check_stock_fulfillment_for_recipes": "0",
"shopping_location_id": null
} }
}, },
"QuantityUnit": { "QuantityUnit": {
@ -3724,7 +3728,8 @@
"allow_partial_units_in_stock": "0", "allow_partial_units_in_stock": "0",
"enable_tare_weight_handling": "0", "enable_tare_weight_handling": "0",
"tare_weight": "0.0", "tare_weight": "0.0",
"not_check_stock_fulfillment_for_recipes": "0" "not_check_stock_fulfillment_for_recipes": "0",
"last_shopping_location_id": null
}, },
"last_purchased": null, "last_purchased": null,
"last_used": null, "last_used": null,

View File

@ -11,6 +11,9 @@ ADD shopping_location_id INTEGER;
ALTER TABLE stock ALTER TABLE stock
ADD shopping_location_id INTEGER; ADD shopping_location_id INTEGER;
ALTER TABLE products
ADD shopping_location_id INTEGER;
DROP VIEW stock_current_locations; DROP VIEW stock_current_locations;
CREATE VIEW stock_current_locations CREATE VIEW stock_current_locations
AS AS

View File

@ -140,7 +140,16 @@ if (Grocy.Components.ProductPicker !== undefined)
function(productDetails) function(productDetails)
{ {
$('#price').val(productDetails.last_price); $('#price').val(productDetails.last_price);
Grocy.Components.ShoppingLocationPicker.SetId(productDetails.last_shopping_location_id);
if (productDetails.last_shopping_location_id != null)
{
Grocy.Components.ShoppingLocationPicker.SetId(productDetails.last_shopping_location_id);
}
else
{
Grocy.Components.ShoppingLocationPicker.SetId(productDetails.default_shopping_location_id);
}
if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING) if (Grocy.FeatureFlags.GROCY_FEATURE_FLAG_STOCK_LOCATION_TRACKING)
{ {
Grocy.Components.LocationPicker.SetId(productDetails.location.id); Grocy.Components.LocationPicker.SetId(productDetails.location.id);

View File

@ -127,6 +127,7 @@ class StockService extends BaseService
$averageShelfLifeDays = intval($this->getDatabase()->stock_average_product_shelf_life()->where('id', $productId)->fetch()->average_shelf_life_days); $averageShelfLifeDays = intval($this->getDatabase()->stock_average_product_shelf_life()->where('id', $productId)->fetch()->average_shelf_life_days);
$lastPrice = null; $lastPrice = null;
$defaultShoppingLocation = null;
$lastShoppingLocation = null; $lastShoppingLocation = null;
$lastLogRow = $this->getDatabase()->stock_log()->where('product_id = :1 AND transaction_type IN (:2, :3) AND undone = 0', $productId, self::TRANSACTION_TYPE_PURCHASE, self::TRANSACTION_TYPE_INVENTORY_CORRECTION)->orderBy('row_created_timestamp', 'DESC')->limit(1)->fetch(); $lastLogRow = $this->getDatabase()->stock_log()->where('product_id = :1 AND transaction_type IN (:2, :3) AND undone = 0', $productId, self::TRANSACTION_TYPE_PURCHASE, self::TRANSACTION_TYPE_INVENTORY_CORRECTION)->orderBy('row_created_timestamp', 'DESC')->limit(1)->fetch();
if ($lastLogRow !== null && !empty($lastLogRow)) if ($lastLogRow !== null && !empty($lastLogRow))
@ -155,6 +156,7 @@ class StockService extends BaseService
'quantity_unit_stock' => $quStock, 'quantity_unit_stock' => $quStock,
'last_price' => $lastPrice, 'last_price' => $lastPrice,
'last_shopping_location_id' => $lastShoppingLocation, 'last_shopping_location_id' => $lastShoppingLocation,
'default_shopping_location_id' => $product->shopping_location_id,
'next_best_before_date' => $nextBestBeforeDate, 'next_best_before_date' => $nextBestBeforeDate,
'location' => $location, 'location' => $location,
'average_shelf_life_days' => $averageShelfLifeDays, 'average_shelf_life_days' => $averageShelfLifeDays,

View File

@ -9,7 +9,7 @@
@php if(empty($nextInputSelector)) { $nextInputSelector = ''; } @endphp @php if(empty($nextInputSelector)) { $nextInputSelector = ''; } @endphp
<div class="form-group" data-next-input-selector="{{ $nextInputSelector }}" data-prefill-by-name="{{ $prefillByName }}" data-prefill-by-id="{{ $prefillById }}"> <div class="form-group" data-next-input-selector="{{ $nextInputSelector }}" data-prefill-by-name="{{ $prefillByName }}" data-prefill-by-id="{{ $prefillById }}">
<label for="shopping_location_id">{{ $__t('Store') }}&nbsp;&nbsp;<span id="{{ $hintId }}" class="small text-muted">{{ $hint }}</span></label> <label for="shopping_location_id">{{ $__t($label) }}&nbsp;&nbsp;<span id="{{ $hintId }}" class="small text-muted">{{ $hint }}</span></label>
<select class="form-control shopping-location-combobox" id="shopping_location_id" name="shopping_location_id" @if($isRequired) required @endif> <select class="form-control shopping-location-combobox" id="shopping_location_id" name="shopping_location_id" @if($isRequired) required @endif>
<option value=""></option> <option value=""></option>
@foreach($shoppinglocations as $shoppinglocation) @foreach($shoppinglocations as $shoppinglocation)

View File

@ -69,7 +69,8 @@
)) ))
@include('components.shoppinglocationpicker', array( @include('components.shoppinglocationpicker', array(
'shoppinglocations' => $shoppinglocations, 'label' => 'Store',
'shoppinglocations' => $shoppinglocations
)) ))
@else @else
<input type="hidden" name="price" id="price" value="0"> <input type="hidden" name="price" id="price" value="0">

View File

@ -88,6 +88,15 @@
<input type="hidden" name="location_id" id="location_id" value="1"> <input type="hidden" name="location_id" id="location_id" value="1">
@endif @endif
@if(GROCY_FEATURE_FLAG_STOCK_PRICE_TRACKING)
@include('components.shoppinglocationpicker', array(
'label' => 'Default store',
'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 @php if($mode == 'edit') { $value = $product->min_stock_amount; } else { $value = 0; } @endphp
@include('components.numberpicker', array( @include('components.numberpicker', array(
'id' => 'min_stock_amount', 'id' => 'min_stock_amount',

View File

@ -87,7 +87,8 @@
<label class="form-check-label" for="price-type-total-price">{{ $__t('Total price') }}</label> <label class="form-check-label" for="price-type-total-price">{{ $__t('Total price') }}</label>
</div> </div>
@include('components.shoppinglocationpicker', array( @include('components.shoppinglocationpicker', array(
'shoppinglocations' => $shoppinglocations, 'label' => 'Store',
'shoppinglocations' => $shoppinglocations
)) ))
@else @else
<input type="hidden" name="price" id="price" value="0"> <input type="hidden" name="price" id="price" value="0">

View File

@ -67,6 +67,7 @@
'isRequired' => false 'isRequired' => false
)) ))
@include('components.shoppinglocationpicker', array( @include('components.shoppinglocationpicker', array(
'label' => 'Store',
'shoppinglocations' => $shoppinglocations, 'shoppinglocations' => $shoppinglocations,
'prefillById' => $stockEntry->shopping_location_id 'prefillById' => $stockEntry->shopping_location_id
)) ))