mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
Squashed commit
Fixed number input min/max amount handling Only (auto) save valid user inputs More filters on the stock journal pages Save the last price per used barcode and preselect that as a total price on purchase if not empty (closes #1131) Don't apply conversions for only_check_single_unit_in_stock ingredients (fixes #1120) Render shopping list userfields (closes #1052) Fixed Focus when adding included recipes (closes #1019) Order all base objects with NOCASE (closes #1086)
This commit is contained in:
parent
1316c1f25f
commit
887526c727
@ -8,6 +8,7 @@
|
||||
### New feature: Prefill purchase data by barcodes
|
||||
- Imagine you buy for example eggs in different pack sizes and they have different barcodes
|
||||
- Each product barcode can be assigned an amount, quantity unit and store (on the product edit page), which is then automatically prefilled on the purchase page
|
||||
- Additionally, the last price per barcode will be tracked and prefilled as a "Total price" on purchase
|
||||
- (Thanks @kriddles for the initial work on this)
|
||||
|
||||
### New feature: User permissions
|
||||
@ -58,6 +59,7 @@
|
||||
- When clicking the product name on the shopping list, the product card will now be displayed (like on the stock overview page) (thanks @kriddles)
|
||||
- On the product card there is now also a button to jump directly to the stock entries of the corresponding product (thanks @kriddles)
|
||||
- The product picker workflows can now also be started by `ENTER` (additionally to `TAB`)
|
||||
- Added more filters on the stock journal page
|
||||
- Added a grouped/summarized stock journal (new button "Journal summary" at the top of the stock journal page) (thanks @fipwmaqzufheoxq92ebc)
|
||||
- Provides an overview of summarized transactions per product, transaction type and user + summarized amount
|
||||
- Fixed that changing the products "Factor purchase to stock quantity unit" not longer messes up historical prices (which results for example in wrong recipe costs) (thanks @kriddles)
|
||||
@ -80,6 +82,7 @@
|
||||
- Decimal amounts are now allowed (for any product, rounded by two decimal places)
|
||||
- Added a button to add all currently in-stock but overdue and expired products to the shopping list (thanks @m-byte)
|
||||
- Improved that when `FEATURE_FLAG_STOCK` is disabled, all product/stock related inputs and buttons are now hidden on the shopping list page (thanks @fipwmaqzufheoxq92ebc)
|
||||
- Shopping list items can now have their own Userfields (entity `shopping_list`), on the shopping list table those fields are rendered additionally to the product Userfields
|
||||
- Fixed that "Add products that are below defined min. stock amount" always rounded up the missing amount to an integral number, this now allows decimal numbers
|
||||
|
||||
### Recipe improvements/fixes
|
||||
@ -130,6 +133,7 @@
|
||||
- Added a "Clear filter"-button on all pages (with filters) to quickly reset applied filters
|
||||
- Prefilled number inputs now use sensible decimal places (max. the configured decimals while hiding trailing zeros where appropriate, means if you never use partial amounts for a product, you'll never see decimals for it)
|
||||
- Improved / more precise validation messages for number inputs
|
||||
- Ordering now happens case-insensitive
|
||||
- The data path (previously fixed to the `data` folder) is now configurable, making it possible to run multiple grocy instances from the same directory (with different `config.php` files / different database, etc.) (thanks @fgrsnau)
|
||||
- Via an environment variable `GROCY_DATAPATH` (higher priority)
|
||||
- Via an FastCGI parameter `GROCY_DATAPATH` (lower priority)
|
||||
|
@ -7,7 +7,7 @@ class BatteriesController extends BaseController
|
||||
public function BatteriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'batteries', [
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name'),
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('batteries'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('batteries')
|
||||
]);
|
||||
@ -41,7 +41,7 @@ class BatteriesController extends BaseController
|
||||
{
|
||||
return $this->renderPage($response, 'batteriesjournal', [
|
||||
'chargeCycles' => $this->getDatabase()->battery_charge_cycles()->orderBy('tracked_time', 'DESC'),
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ class BatteriesController extends BaseController
|
||||
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['batteries_due_soon_days'];
|
||||
|
||||
return $this->renderPage($response, 'batteriesoverview', [
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name'),
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'current' => $this->getBatteriesService()->GetCurrent(),
|
||||
'nextXDays' => $nextXDays,
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('batteries'),
|
||||
@ -62,7 +62,7 @@ class BatteriesController extends BaseController
|
||||
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'batterytracking', [
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name')
|
||||
'batteries' => $this->getDatabase()->batteries()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class ChoresController extends BaseController
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
||||
'users' => $users,
|
||||
'products' => $this->getDatabase()->products()->orderBy('name')
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
else
|
||||
@ -29,7 +29,7 @@ class ChoresController extends BaseController
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||
'assignmentTypes' => GetClassConstants('\Grocy\Services\ChoresService', 'CHORE_ASSIGNMENT_TYPE_'),
|
||||
'users' => $users,
|
||||
'products' => $this->getDatabase()->products()->orderBy('name')
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@ class ChoresController extends BaseController
|
||||
public function ChoresList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'chores', [
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('chores')
|
||||
]);
|
||||
@ -52,7 +52,7 @@ class ChoresController extends BaseController
|
||||
{
|
||||
return $this->renderPage($response, 'choresjournal', [
|
||||
'choresLog' => $this->getDatabase()->chores_log()->orderBy('tracked_time', 'DESC'),
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $this->getDatabase()->users()->orderBy('username')
|
||||
]);
|
||||
}
|
||||
@ -63,7 +63,7 @@ class ChoresController extends BaseController
|
||||
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['chores_due_soon_days'];
|
||||
|
||||
return $this->renderPage($response, 'choresoverview', [
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'currentChores' => $this->getChoresService()->GetCurrent(),
|
||||
'nextXDays' => $nextXDays,
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('chores'),
|
||||
@ -75,7 +75,7 @@ class ChoresController extends BaseController
|
||||
public function TrackChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'choretracking', [
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name'),
|
||||
'chores' => $this->getDatabase()->chores()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $this->getDatabase()->users()->orderBy('username')
|
||||
]);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class EquipmentController extends BaseController
|
||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'equipment', [
|
||||
'equipment' => $this->getDatabase()->equipment()->orderBy('name'),
|
||||
'equipment' => $this->getDatabase()->equipment()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('equipment'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('equipment')
|
||||
]);
|
||||
|
@ -7,7 +7,7 @@ class GenericEntityController extends BaseController
|
||||
public function UserentitiesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'userentities', [
|
||||
'userentities' => $this->getDatabase()->userentities()->orderBy('name')
|
||||
'userentities' => $this->getDatabase()->userentities()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -46,15 +46,15 @@ class RecipesController extends BaseController
|
||||
'recipes' => $recipes,
|
||||
'internalRecipes' => $this->getDatabase()->recipes()->whereNot('type', RecipesService::RECIPE_TYPE_NORMAL)->fetchAll(),
|
||||
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
|
||||
public function Overview(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
$recipes = $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name');
|
||||
$recipes = $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name', 'COLLATE NOCASE');
|
||||
$recipesResolved = $this->getRecipesService()->GetRecipesResolved();
|
||||
|
||||
$selectedRecipe = null;
|
||||
@ -99,7 +99,7 @@ class RecipesController extends BaseController
|
||||
|
||||
if ($selectedRecipe)
|
||||
{
|
||||
$selectedRecipeSubRecipes = $this->getDatabase()->recipes()->where('id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('name')->fetchAll();
|
||||
$selectedRecipeSubRecipes = $this->getDatabase()->recipes()->where('id IN (SELECT includes_recipe_id FROM recipes_nestings_resolved WHERE recipe_id = :1 AND includes_recipe_id != :1)', $selectedRecipe->id)->orderBy('name', 'COLLATE NOCASE')->fetchAll();
|
||||
|
||||
$includedRecipeIdsAbsolute = [];
|
||||
$includedRecipeIdsAbsolute[] = $selectedRecipe->id;
|
||||
@ -132,11 +132,11 @@ class RecipesController extends BaseController
|
||||
'recipe' => $this->getDatabase()->recipes($recipeId),
|
||||
'recipePositions' => $this->getDatabase()->recipes_pos()->where('recipe_id', $recipeId),
|
||||
'mode' => $recipeId == 'new' ? 'create' : 'edit',
|
||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units(),
|
||||
'recipePositionsResolved' => $this->getRecipesService()->GetRecipesPosResolved(),
|
||||
'recipesResolved' => $this->getRecipesService()->GetRecipesResolved(),
|
||||
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name'),
|
||||
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name', 'COLLATE NOCASE'),
|
||||
'recipeNestings' => $this->getDatabase()->recipes_nestings()->where('recipe_id', $recipeId),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('recipes'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
@ -151,8 +151,8 @@ class RecipesController extends BaseController
|
||||
'mode' => 'create',
|
||||
'recipe' => $this->getDatabase()->recipes($args['recipeId']),
|
||||
'recipePos' => new \stdClass(),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
@ -162,8 +162,8 @@ class RecipesController extends BaseController
|
||||
'mode' => 'edit',
|
||||
'recipe' => $this->getDatabase()->recipes($args['recipeId']),
|
||||
'recipePos' => $this->getDatabase()->recipes_pos($args['recipePosId']),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ class StockController extends BaseController
|
||||
return $this->renderPage($response, 'consume', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'barcodes' => $productBarcodes,
|
||||
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'recipes' => $this->getDatabase()->recipes()->where('type', RecipesService::RECIPE_TYPE_NORMAL)->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
@ -27,29 +27,34 @@ class StockController extends BaseController
|
||||
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
|
||||
return $this->renderPage($response, 'inventory', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'barcodes' => $productBarcodes,
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
|
||||
public function Journal(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
$usersService = $this->getUsersService();
|
||||
|
||||
return $this->renderPage($response, 'stockjournal', [
|
||||
'stockLog' => $this->getDatabase()->uihelper_stock_journal()->orderBy('row_created_timestamp', 'DESC'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $usersService->GetUsersAsDto(),
|
||||
'transactionTypes' => GetClassConstants('\Grocy\Services\StockService', 'TRANSACTION_TYPE_'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function LocationContentSheet(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'locationcontentsheet', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'currentStockLocationContent' => $this->getStockService()->GetCurrentStockLocationContent()
|
||||
]);
|
||||
}
|
||||
@ -76,7 +81,7 @@ class StockController extends BaseController
|
||||
public function LocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'locations', [
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('locations'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('locations')
|
||||
]);
|
||||
@ -89,10 +94,10 @@ class StockController extends BaseController
|
||||
|
||||
return $this->renderPage($response, 'stockoverview', [
|
||||
'currentStock' => $this->getStockService()->GetCurrentStockOverview(),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
||||
'nextXDays' => $nextXDays,
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||
]);
|
||||
@ -113,9 +118,10 @@ class StockController extends BaseController
|
||||
'mode' => 'create',
|
||||
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
||||
'product' => $product,
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('product_barcodes')
|
||||
]);
|
||||
}
|
||||
else
|
||||
@ -124,9 +130,10 @@ class StockController extends BaseController
|
||||
'mode' => 'edit',
|
||||
'barcode' => $this->getDatabase()->product_barcodes($args['productBarcodeId']),
|
||||
'product' => $product,
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('product_barcodes')
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -138,11 +145,11 @@ class StockController extends BaseController
|
||||
return $this->renderPage($response, 'productform', [
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL and active = 1')->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('parent_product_id IS NULL and active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'isSubProductOfOthers' => false,
|
||||
'mode' => 'create'
|
||||
]);
|
||||
@ -153,16 +160,18 @@ class StockController extends BaseController
|
||||
|
||||
return $this->renderPage($response, 'productform', [
|
||||
'product' => $product,
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'barcodes' => $this->getDatabase()->product_barcodes()->orderBy('barcode'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'productgroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL and active = 1', $product->id)->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('id != :1 AND parent_product_id IS NULL and active = 1', $product->id)->orderBy('name', 'COLLATE NOCASE'),
|
||||
'isSubProductOfOthers' => $this->getDatabase()->products()->where('parent_product_id = :1', $product->id)->count() !== 0,
|
||||
'mode' => 'edit',
|
||||
'quConversions' => $this->getDatabase()->quantity_unit_conversions()
|
||||
'quConversions' => $this->getDatabase()->quantity_unit_conversions(),
|
||||
'productBarcodeUserfields' => $this->getUserfieldsService()->GetFields('product_barcodes'),
|
||||
'productBarcodeUserfieldValues' => $this->getUserfieldsService()->GetAllValues('product_barcodes')
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -189,8 +198,8 @@ class StockController extends BaseController
|
||||
public function ProductGroupsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'productgroups', [
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('product_groups'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('product_groups')
|
||||
]);
|
||||
@ -199,10 +208,10 @@ class StockController extends BaseController
|
||||
public function ProductsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'products', [
|
||||
'products' => $this->getDatabase()->products()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||
]);
|
||||
@ -214,11 +223,11 @@ class StockController extends BaseController
|
||||
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
|
||||
return $this->renderPage($response, 'purchase', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'barcodes' => $productBarcodes,
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
@ -244,7 +253,7 @@ class StockController extends BaseController
|
||||
return $this->renderPage($response, 'quantityunitconversionform', [
|
||||
'mode' => 'create',
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_unit_conversions'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'product' => $product,
|
||||
'defaultQuUnit' => $defaultQuUnit
|
||||
]);
|
||||
@ -255,7 +264,7 @@ class StockController extends BaseController
|
||||
'quConversion' => $this->getDatabase()->quantity_unit_conversions($args['quConversionId']),
|
||||
'mode' => 'edit',
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_unit_conversions'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'product' => $product,
|
||||
'defaultQuUnit' => $defaultQuUnit
|
||||
]);
|
||||
@ -292,14 +301,14 @@ class StockController extends BaseController
|
||||
public function QuantityUnitPluralFormTesting(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'quantityunitpluraltesting', [
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name')
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
public function QuantityUnitsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'quantityunits', [
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('quantity_units'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('quantity_units')
|
||||
]);
|
||||
@ -316,15 +325,17 @@ class StockController extends BaseController
|
||||
|
||||
return $this->renderPage($response, 'shoppinglist', [
|
||||
'listItems' => $this->getDatabase()->shopping_list()->where('shopping_list_id = :1', $listId),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'missingProducts' => $this->getStockService()->GetMissingProducts(),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'selectedShoppingListId' => $listId,
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('products')
|
||||
'productUserfields' => $this->getUserfieldsService()->GetFields('products'),
|
||||
'productUserfieldValues' => $this->getUserfieldsService()->GetAllValues('products'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_list'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('shopping_list')
|
||||
]);
|
||||
}
|
||||
|
||||
@ -333,14 +344,16 @@ class StockController extends BaseController
|
||||
if ($args['listId'] == 'new')
|
||||
{
|
||||
return $this->renderPage($response, 'shoppinglistform', [
|
||||
'mode' => 'create'
|
||||
'mode' => 'create',
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_lists')
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->renderPage($response, 'shoppinglistform', [
|
||||
'shoppingList' => $this->getDatabase()->shopping_lists($args['listId']),
|
||||
'mode' => 'edit'
|
||||
'mode' => 'edit',
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_lists')
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -350,22 +363,24 @@ class StockController extends BaseController
|
||||
if ($args['itemId'] == 'new')
|
||||
{
|
||||
return $this->renderPage($response, 'shoppinglistitemform', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'mode' => 'create',
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_list')
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->renderPage($response, 'shoppinglistitemform', [
|
||||
'listItem' => $this->getDatabase()->shopping_list($args['itemId']),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppingLists' => $this->getDatabase()->shopping_lists()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'mode' => 'edit',
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_list')
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -397,7 +412,7 @@ class StockController extends BaseController
|
||||
public function ShoppingLocationsList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'shoppinglocations', [
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('shopping_locations'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('shopping_locations')
|
||||
]);
|
||||
@ -407,18 +422,18 @@ class StockController extends BaseController
|
||||
{
|
||||
return $this->renderPage($response, 'stockentryform', [
|
||||
'stockEntry' => $this->getDatabase()->stock()->where('id', $args['entryId'])->fetch(),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name')
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
public function StockSettings(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'stocksettings', [
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name')
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'productGroups' => $this->getDatabase()->product_groups()->orderBy('name', 'COLLATE NOCASE')
|
||||
]);
|
||||
}
|
||||
|
||||
@ -428,10 +443,10 @@ class StockController extends BaseController
|
||||
$nextXDays = $usersService->GetUserSettings(GROCY_USER_ID)['stock_due_soon_days'];
|
||||
|
||||
return $this->renderPage($response, 'stockentries', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityunits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'shoppinglocations' => $this->getDatabase()->shopping_locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'stockEntries' => $this->getDatabase()->stock()->orderBy('product_id'),
|
||||
'currentStockLocations' => $this->getStockService()->GetCurrentStockLocations(),
|
||||
'nextXDays' => $nextXDays,
|
||||
@ -446,10 +461,10 @@ class StockController extends BaseController
|
||||
$productBarcodes = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
|
||||
return $this->renderPage($response, 'transfer', [
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name'),
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'barcodes' => $productBarcodes,
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name'),
|
||||
'locations' => $this->getDatabase()->locations()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnits' => $this->getDatabase()->quantity_units()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'quantityUnitConversionsResolved' => $this->getDatabase()->quantity_unit_conversions_resolved()
|
||||
]);
|
||||
}
|
||||
@ -474,8 +489,13 @@ class StockController extends BaseController
|
||||
{
|
||||
$entries = $entries->where('transaction_type', $request->getQueryParams()['transaction_type']);
|
||||
}
|
||||
|
||||
$usersService = $this->getUsersService();
|
||||
return $this->renderPage($response, 'stockjournalsummary', [
|
||||
'entries' => $entries
|
||||
'entries' => $entries,
|
||||
'products' => $this->getDatabase()->products()->where('active = 1')->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $usersService->GetUsersAsDto(),
|
||||
'transactionTypes' => GetClassConstants('\Grocy\Services\StockService', 'TRANSACTION_TYPE_')
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ class TasksController extends BaseController
|
||||
{
|
||||
if (isset($request->getQueryParams()['include_done']))
|
||||
{
|
||||
$tasks = $this->getDatabase()->tasks()->orderBy('name');
|
||||
$tasks = $this->getDatabase()->tasks()->orderBy('name', 'COLLATE NOCASE');
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -21,7 +21,7 @@ class TasksController extends BaseController
|
||||
return $this->renderPage($response, 'tasks', [
|
||||
'tasks' => $tasks,
|
||||
'nextXDays' => $nextXDays,
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $this->getDatabase()->users(),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('tasks'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('tasks')
|
||||
@ -31,7 +31,7 @@ class TasksController extends BaseController
|
||||
public function TaskCategoriesList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->renderPage($response, 'taskcategories', [
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('task_categories'),
|
||||
'userfieldValues' => $this->getUserfieldsService()->GetAllValues('task_categories')
|
||||
]);
|
||||
@ -62,7 +62,7 @@ class TasksController extends BaseController
|
||||
{
|
||||
return $this->renderPage($response, 'taskform', [
|
||||
'mode' => 'create',
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $this->getDatabase()->users()->orderBy('username'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
||||
]);
|
||||
@ -72,7 +72,7 @@ class TasksController extends BaseController
|
||||
return $this->renderPage($response, 'taskform', [
|
||||
'task' => $this->getDatabase()->tasks($args['taskId']),
|
||||
'mode' => 'edit',
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name'),
|
||||
'taskCategories' => $this->getDatabase()->task_categories()->orderBy('name', 'COLLATE NOCASE'),
|
||||
'users' => $this->getDatabase()->users()->orderBy('username'),
|
||||
'userfields' => $this->getUserfieldsService()->GetFields('tasks')
|
||||
]);
|
||||
|
@ -239,6 +239,9 @@
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/StockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ProductBarcode"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -311,6 +314,9 @@
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/StockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ProductBarcode"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -402,6 +408,9 @@
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/StockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ProductBarcode"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -482,6 +491,9 @@
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/StockEntry"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/ProductBarcode"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -4129,7 +4141,7 @@
|
||||
"$ref": "#/components/schemas/Product"
|
||||
},
|
||||
"product_barcodes": {
|
||||
"$ref": "#/components/schemas/ProductBarcodeDetailsResponse"
|
||||
"$ref": "#/components/schemas/ProductBarcode"
|
||||
},
|
||||
"default_quantity_unit_purchase": {
|
||||
"$ref": "#/components/schemas/QuantityUnit"
|
||||
@ -4257,14 +4269,14 @@
|
||||
},
|
||||
"price": {
|
||||
"type": "number",
|
||||
"format": "number"
|
||||
"format": "float"
|
||||
},
|
||||
"shopping_location": {
|
||||
"$ref": "#/components/schemas/ShoppingLocation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ProductBarcodeDetailsResponse": {
|
||||
"ProductBarcode": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {
|
||||
@ -4282,6 +4294,10 @@
|
||||
"amount": {
|
||||
"type": "number",
|
||||
"format": "number"
|
||||
},
|
||||
"last_price": {
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -889,9 +889,6 @@ msgstr ""
|
||||
msgid "Shopping list to stock workflow"
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically do the booking using the last price and the amount of the shopping list item, if the product has \"Default best before days\" set"
|
||||
msgstr ""
|
||||
|
||||
msgid "Skip"
|
||||
msgstr ""
|
||||
|
||||
@ -1975,3 +1972,6 @@ msgstr ""
|
||||
|
||||
msgid "This must between %1$s and %2$s and needs to be a valid number with max. %3$s decimal places"
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically do the booking using the last price and the amount of the shopping list item, if the product has \"Default due days\" set"
|
||||
msgstr ""
|
||||
|
@ -16,6 +16,7 @@ CREATE TABLE product_barcodes (
|
||||
qu_id INT,
|
||||
amount REAL,
|
||||
shopping_location_id INTEGER,
|
||||
last_price DECIMAL(15, 2),
|
||||
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime'))
|
||||
);
|
||||
|
||||
|
@ -424,7 +424,7 @@ Grocy.FrontendHelpers.ShowGenericError = function(message, exception)
|
||||
{
|
||||
bootbox.alert({
|
||||
title: __t('Error details'),
|
||||
message: JSON.stringify(exception, null, 4),
|
||||
message: '<pre class="my-0"><code>' + JSON.stringify(exception, null, 4) + '</code></pre>',
|
||||
closeButton: false
|
||||
});
|
||||
}
|
||||
@ -448,6 +448,11 @@ $(document).on("change", ".user-setting-control", function()
|
||||
var element = $(this);
|
||||
var settingKey = element.attr("data-setting-key");
|
||||
|
||||
if (!element[0].checkValidity())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var inputType = "unknown";
|
||||
if (typeof element.attr("type") !== typeof undefined && element.attr("type") !== false)
|
||||
{
|
||||
|
@ -133,7 +133,7 @@ $('.input-group-chore-period-type').on('change', function(e)
|
||||
{
|
||||
$("label[for='period_days']").text(__t("Period days"));
|
||||
$("#period_days").attr("min", "0");
|
||||
$("#period_days").attr("max", "999999");
|
||||
$("#period_days").removeAttr("max");
|
||||
$('#chore-period-type-info').attr("data-original-title", __t('This means the next execution of this chore is scheduled %s days after the last execution', periodDays.toString()));
|
||||
}
|
||||
else if (periodType === 'daily')
|
||||
|
@ -32,30 +32,38 @@ $(".numberpicker").each(function()
|
||||
{
|
||||
mutations.forEach(function(mutation)
|
||||
{
|
||||
if (mutation.type == "attributes" && (mutation.attributeName == "min" || mutation.attributeName == "max" || mutation.attributeName == "data-not-equal"))
|
||||
if (mutation.type == "attributes" && (mutation.attributeName == "min" || mutation.attributeName == "max" || mutation.attributeName == "data-not-equal" || mutation.attributeName == "data-initialised"))
|
||||
{
|
||||
var element = $(mutation.target);
|
||||
var min = element.attr("min");
|
||||
var max = element.attr("max");
|
||||
var decimals = element.attr("data-decimals");
|
||||
|
||||
var max = "";
|
||||
if (element.hasAttr("max"))
|
||||
{
|
||||
max = element.attr("max");
|
||||
}
|
||||
|
||||
if (element.hasAttr("data-not-equal"))
|
||||
{
|
||||
var notEqual = element.attr("data-not-equal");
|
||||
|
||||
if (max.isEmpty() || max.startsWith("999999"))
|
||||
if (notEqual != "NaN")
|
||||
{
|
||||
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s or equal %2$s and needs to be a valid number with max. %3$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
|
||||
}
|
||||
else
|
||||
{
|
||||
element.parent().find(".invalid-feedback").text(__t("This must be between %1$s and %2$s, cannot equal %3$s and needs to be a valid number with max. %4$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(max).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals }), decimals));
|
||||
}
|
||||
if (max.isEmpty())
|
||||
{
|
||||
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s or equal %2$s and needs to be a valid number with max. %3$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
|
||||
}
|
||||
else
|
||||
{
|
||||
element.parent().find(".invalid-feedback").text(__t("This must be between %1$s and %2$s, cannot equal %3$s and needs to be a valid number with max. %4$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(max).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), parseFloat(notEqual).toLocaleString(undefined, { minimumFractionDigits: decimals, maximumFractionDigits: decimals }), decimals));
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (max.isEmpty() || max.startsWith("999999"))
|
||||
if (max.isEmpty())
|
||||
{
|
||||
element.parent().find(".invalid-feedback").text(__t("This cannot be lower than %1$s and needs to be a valid number with max. %2$s decimal places", parseFloat(min).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: decimals }), decimals));
|
||||
}
|
||||
@ -69,4 +77,4 @@ $(".numberpicker").each(function()
|
||||
attributes: true
|
||||
});
|
||||
});
|
||||
$(".numberpicker").attr("min", $(".numberpicker").attr("min")); // Dummy change to trigger MutationObserver above once
|
||||
$(".numberpicker").attr("data-initialised", "true"); // Dummy change to trigger MutationObserver above once
|
||||
|
@ -93,7 +93,7 @@
|
||||
|
||||
Grocy.Components.ProductAmountPicker.Reset();
|
||||
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
|
||||
$("#display_amount").attr("max", "999999");
|
||||
$("#display_amount").removeAttr("max");
|
||||
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_consume_amount));
|
||||
RefreshLocaleNumberInput();
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
@ -272,6 +272,8 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
||||
Grocy.Api.Get('stock/products/' + productId,
|
||||
function(productDetails)
|
||||
{
|
||||
current_productDetails = productDetails;
|
||||
|
||||
Grocy.Components.ProductAmountPicker.Reload(productDetails.product.id, productDetails.quantity_unit_stock.id);
|
||||
Grocy.Components.ProductAmountPicker.SetQuantityUnit(productDetails.quantity_unit_stock.id);
|
||||
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_consume_amount));
|
||||
@ -473,6 +475,11 @@ $("#use_specific_stock_entry").on("change", function()
|
||||
Grocy.FrontendHelpers.ValidateForm("consume-form");
|
||||
});
|
||||
|
||||
$("#qu_id").on("change", function()
|
||||
{
|
||||
RefreshForm();
|
||||
});
|
||||
|
||||
function UndoStockBooking(bookingId)
|
||||
{
|
||||
Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
|
||||
@ -570,7 +577,7 @@ function RefreshForm()
|
||||
$("#tare-weight-handling-info").addClass("d-none");
|
||||
|
||||
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
|
||||
$('#display_amount').attr('max', sumValue);
|
||||
$('#display_amount').attr('max', sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
|
||||
|
||||
if (sumValue == 0)
|
||||
{
|
||||
|
@ -84,6 +84,7 @@
|
||||
$("#tare-weight-handling-info").addClass("d-none");
|
||||
$("#display_amount").attr("min", "0");
|
||||
$('#display_amount').val('');
|
||||
$('#display_amount').removeAttr("data-not-equal");
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
$('#price').val('');
|
||||
Grocy.Components.DateTimePicker.Clear();
|
||||
|
@ -13,6 +13,11 @@
|
||||
Grocy.Api.Post('objects/product_barcodes', jsonData,
|
||||
function(result)
|
||||
{
|
||||
Grocy.EditObjectId = result.created_object_id;
|
||||
Grocy.Components.UserfieldsForm.Save()
|
||||
|
||||
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@ -23,9 +28,12 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.Components.UserfieldsForm.Save();
|
||||
Grocy.Api.Put('objects/product_barcodes/' + Grocy.EditObjectId, jsonData,
|
||||
function(result)
|
||||
{
|
||||
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@ -34,9 +42,6 @@
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
window.parent.postMessage(WindowMessageBag("ProductBarcodesChanged"), U("/product/" + GetUriParam("product")));
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), U("/product/" + GetUriParam("product")));
|
||||
});
|
||||
|
||||
$('#barcode').on('keyup', function(e)
|
||||
@ -82,3 +87,4 @@ if (Grocy.EditMode == "edit")
|
||||
Grocy.FrontendHelpers.ValidateForm('barcode-form');
|
||||
$('#barcode').focus();
|
||||
RefreshLocaleNumberInput();
|
||||
Grocy.Components.UserfieldsForm.Load()
|
||||
|
@ -296,7 +296,7 @@ var quConversionsTable = $('#qu-conversions-table-products').DataTable({
|
||||
dataSrc: 4
|
||||
}
|
||||
});
|
||||
$('#qu-conversions-table tbody').removeClass("d-none");
|
||||
$('#qu-conversions-table-products tbody').removeClass("d-none");
|
||||
quConversionsTable.columns.adjust().draw();
|
||||
|
||||
var barcodeTable = $('#barcode-table').DataTable({
|
||||
|
@ -55,6 +55,16 @@ $('#save-purchase-button').on('click', function(e)
|
||||
Grocy.Api.Post('stock/products/' + jsonForm.product_id + '/add', jsonData,
|
||||
function(result)
|
||||
{
|
||||
if ($("#purchase-form").hasAttr("data-used-barcode"))
|
||||
{
|
||||
Grocy.Api.Put('objects/product_barcodes/' + $("#purchase-form").attr("data-used-barcode"), { last_price: $("#price").val() / $("#display_amount").val() },
|
||||
function(result)
|
||||
{ },
|
||||
function(xhr)
|
||||
{ }
|
||||
);
|
||||
}
|
||||
|
||||
if (BoolVal(Grocy.UserSettings.scan_mode_purchase_enabled))
|
||||
{
|
||||
Grocy.UISound.Success();
|
||||
@ -108,6 +118,7 @@ $('#save-purchase-button').on('click', function(e)
|
||||
}
|
||||
|
||||
Grocy.Components.ProductAmountPicker.Reset();
|
||||
$("#purchase-form").removeAttr("data-used-barcode");
|
||||
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
|
||||
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_purchase_amount));
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
@ -202,7 +213,7 @@ if (Grocy.Components.ProductPicker !== undefined)
|
||||
Grocy.Components.LocationPicker.SetId(productDetails.location.id);
|
||||
}
|
||||
|
||||
if (productDetails.last_price == null)
|
||||
if (productDetails.last_price == null || productDetails.last_price == 0)
|
||||
{
|
||||
$("#price").val("")
|
||||
}
|
||||
@ -282,10 +293,11 @@ if (Grocy.Components.ProductPicker !== undefined)
|
||||
if (barcodeResult != null)
|
||||
{
|
||||
var barcode = barcodeResult[0];
|
||||
$("#purchase-form").attr("data-used-barcode", barcode.id);
|
||||
|
||||
if (barcode != null)
|
||||
{
|
||||
if (barcode.amount != null)
|
||||
if (barcode.amount != null && !barcode.amount.isEmpty())
|
||||
{
|
||||
$("#display_amount").val(barcode.amount);
|
||||
$("#display_amount").select();
|
||||
@ -301,6 +313,12 @@ if (Grocy.Components.ProductPicker !== undefined)
|
||||
Grocy.Components.ShoppingLocationPicker.SetId(barcode.shopping_location_id);
|
||||
}
|
||||
|
||||
if (barcode.last_price != null && !barcode.last_price.isEmpty())
|
||||
{
|
||||
$("#price").val(barcode.last_price);
|
||||
$("#price-type-total-price").click();
|
||||
}
|
||||
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
Grocy.FrontendHelpers.ValidateForm('purchase-form');
|
||||
}
|
||||
@ -312,6 +330,10 @@ if (Grocy.Components.ProductPicker !== undefined)
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#purchase-form").removeAttr("data-used-barcode");
|
||||
}
|
||||
|
||||
$('#display_amount').trigger("keyup");
|
||||
},
|
||||
@ -450,7 +472,7 @@ function refreshPriceHint()
|
||||
price = parseFloat(price / $('#display_amount').val()).toFixed(Grocy.UserSettings.stock_decimal_places_prices);
|
||||
}
|
||||
|
||||
$('#price-hint').text(__t('means %1$s per %2$s', price.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: 2, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), $("#qu_id").attr("data-destination-qu-name")));
|
||||
$('#price-hint').text(__t('means %1$s per %2$s', price.toLocaleString(undefined, { style: "currency", currency: Grocy.Currency, minimumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_prices }), $("#qu_id").attr("data-destination-qu-name")));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -285,6 +285,7 @@ $("#recipe-include-add-button").on("click", function(e)
|
||||
$("#recipe-include-editform-title").text(__t("Add included recipe"));
|
||||
$("#recipe-include-form").data("edit-mode", "create");
|
||||
Grocy.Components.RecipePicker.Clear();
|
||||
Grocy.Components.RecipePicker.GetInputElement().focus();
|
||||
$("#recipe-include-editform-modal").modal("show");
|
||||
Grocy.FrontendHelpers.ValidateForm("recipe-include-form");
|
||||
},
|
||||
|
@ -10,9 +10,13 @@
|
||||
Grocy.Api.Post('objects/shopping_lists', jsonData,
|
||||
function(result)
|
||||
{
|
||||
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", result.created_object_id), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
|
||||
Grocy.EditObjectId = result.created_object_id;
|
||||
Grocy.Components.UserfieldsForm.Save(function()
|
||||
{
|
||||
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", result.created_object_id), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
|
||||
});
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@ -23,19 +27,22 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.Api.Put('objects/shopping_lists/' + Grocy.EditObjectId, jsonData,
|
||||
function(result)
|
||||
{
|
||||
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", Grocy.EditObjectId), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("shopping-list-form");
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
Grocy.Components.UserfieldsForm.Save(function()
|
||||
{
|
||||
Grocy.Api.Put('objects/shopping_lists/' + Grocy.EditObjectId, jsonData,
|
||||
function(result)
|
||||
{
|
||||
window.parent.postMessage(WindowMessageBag("ShoppingListChanged", Grocy.EditObjectId), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("Ready"), Grocy.BaseUrl);
|
||||
window.parent.postMessage(WindowMessageBag("CloseAllModals"), Grocy.BaseUrl);
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("shopping-list-form");
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -61,5 +68,6 @@ $('#shopping-list-form input').keydown(function(event)
|
||||
}
|
||||
});
|
||||
|
||||
Grocy.Components.UserfieldsForm.Load();
|
||||
$('#name').focus();
|
||||
Grocy.FrontendHelpers.ValidateForm('shopping-list-form');
|
||||
|
@ -21,6 +21,9 @@ $('#save-shoppinglist-button').on('click', function(e)
|
||||
Grocy.Api.Post('stock/shoppinglist/add-product', jsonData,
|
||||
function(result)
|
||||
{
|
||||
Grocy.EditObjectId = result.created_object_id;
|
||||
Grocy.Components.UserfieldsForm.Save();
|
||||
|
||||
if (GetUriParam("embedded") !== undefined)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + jsonData.product_id,
|
||||
@ -54,6 +57,9 @@ $('#save-shoppinglist-button').on('click', function(e)
|
||||
Grocy.Api.Post('objects/shopping_list', jsonData,
|
||||
function(result)
|
||||
{
|
||||
Grocy.EditObjectId = result.created_object_id;
|
||||
Grocy.Components.UserfieldsForm.Save();
|
||||
|
||||
if (GetUriParam("embedded") !== undefined)
|
||||
{
|
||||
if (jsonData.product_id)
|
||||
@ -94,6 +100,8 @@ $('#save-shoppinglist-button').on('click', function(e)
|
||||
Grocy.Api.Put('objects/shopping_list/' + Grocy.EditObjectId, jsonData,
|
||||
function(result)
|
||||
{
|
||||
Grocy.Components.UserfieldsForm.Save();
|
||||
|
||||
if (GetUriParam("embedded") !== undefined)
|
||||
{
|
||||
if (jsonData.product_id)
|
||||
@ -216,3 +224,5 @@ if (GetUriParam("amount") !== undefined)
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
Grocy.FrontendHelpers.ValidateForm('shoppinglist-form');
|
||||
}
|
||||
|
||||
Grocy.Components.UserfieldsForm.Load();
|
||||
|
@ -23,6 +23,42 @@ $("#product-filter").on("change", function()
|
||||
stockJournalTable.column(1).search(text).draw();
|
||||
});
|
||||
|
||||
$("#transaction-type-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#transaction-type-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(4).search(text).draw();
|
||||
});
|
||||
|
||||
$("#location-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#location-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(5).search(text).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#user-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(6).search(text).draw();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
@ -37,6 +73,12 @@ $("#search").on("keyup", Delay(function()
|
||||
$("#clear-filter-button").on("click", function()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#transaction-type-filter").val("all");
|
||||
$("#location-filter").val("all");
|
||||
$("#user-filter").val("all");
|
||||
stockJournalTable.column(4).search("").draw();
|
||||
stockJournalTable.column(5).search("").draw();
|
||||
stockJournalTable.column(6).search("").draw();
|
||||
stockJournalTable.search("").draw();
|
||||
});
|
||||
|
||||
|
@ -1,8 +1,71 @@
|
||||
var journalSummaryTable = $('#journal-summary-table').DataTable({
|
||||
var journalSummaryTable = $('#stock-journal-summary-table').DataTable({
|
||||
'paginate': true,
|
||||
'order': [[0, 'desc']]
|
||||
'order': [[1, 'asc']],
|
||||
'columnDefs': [
|
||||
{ 'orderable': false, 'targets': 0 },
|
||||
{ 'searchable': false, "targets": 0 }
|
||||
]
|
||||
});
|
||||
$('#journal-summary-table tbody').removeClass("d-none");
|
||||
$('#stock-journal-summary-table tbody').removeClass("d-none");
|
||||
journalSummaryTable.columns.adjust().draw();
|
||||
$('.dataTables_scrollBody').addClass("dragscroll");
|
||||
dragscroll.reset();
|
||||
|
||||
$("#product-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#product-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.column(1).search(text).draw();
|
||||
});
|
||||
|
||||
$("#transaction-type-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#transaction-type-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.column(2).search(text).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#user-filter option:selected").text();
|
||||
if (value === "all")
|
||||
{
|
||||
text = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.column(3).search(text).draw();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.search(value).draw();
|
||||
}, 200));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#transaction-type-filter").val("all");
|
||||
$("#location-filter").val("all");
|
||||
$("#user-filter").val("all");
|
||||
journalSummaryTable.column(1).search("").draw();
|
||||
journalSummaryTable.column(2).search("").draw();
|
||||
journalSummaryTable.column(3).search("").draw();
|
||||
journalSummaryTable.search("").draw();
|
||||
});
|
||||
|
@ -90,7 +90,7 @@
|
||||
Grocy.Components.ProductAmountPicker.Reset();
|
||||
$("#location_id_from").find("option").remove().end().append("<option></option>");
|
||||
$("#display_amount").attr("min", "0." + "0".repeat(parseInt(Grocy.UserSettings.stock_decimal_places_amounts) - 1) + "1");
|
||||
$("#display_amount").attr("max", "999999");
|
||||
$("#display_amount").removeAttr("max");
|
||||
$('#display_amount').val(parseFloat(Grocy.UserSettings.stock_default_transfer_amount));
|
||||
RefreshLocaleNumberInput();
|
||||
$(".input-group-productamountpicker").trigger("change");
|
||||
@ -198,6 +198,8 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
||||
$("#tare-weight-handling-info").addClass("d-none");
|
||||
}
|
||||
|
||||
$('#display_amount').attr("data-stock-amount", productDetails.stock_amount);
|
||||
|
||||
if ((parseFloat(productDetails.stock_amount) || 0) === 0)
|
||||
{
|
||||
Grocy.Components.ProductPicker.Clear();
|
||||
@ -274,7 +276,7 @@ $("#location_id_from").on('change', function(e)
|
||||
sumValue = sumValue + parseFloat(stockEntry.amount);
|
||||
}
|
||||
});
|
||||
$("#display_amount").attr("max", sumValue);
|
||||
$("#display_amount").attr("max", sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#display_amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
|
||||
@ -299,6 +301,11 @@ $("#location_id_to").on('change', function(e)
|
||||
}
|
||||
});
|
||||
|
||||
$("#qu_id").on('change', function(e)
|
||||
{
|
||||
$("#display_amount").attr("max", parseFloat($('#display_amount').attr("data-stock-amount")) * $("#qu_id option:selected").attr("data-qu-factor"));
|
||||
});
|
||||
|
||||
$('#display_amount').on('focus', function(e)
|
||||
{
|
||||
$(this).select();
|
||||
@ -346,7 +353,7 @@ $("#specific_stock_entry").on("change", function(e)
|
||||
sumValue = sumValue + parseFloat(stockEntry.amount);
|
||||
}
|
||||
});
|
||||
$("#display_amount").attr("max", sumValue);
|
||||
$("#display_amount").attr("max", sumValue * $("#qu_id option:selected").attr("data-qu-factor"));
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#display_amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
|
||||
|
@ -21,7 +21,7 @@ class UserfieldsService extends BaseService
|
||||
|
||||
public function GetAllFields()
|
||||
{
|
||||
return $this->getDatabase()->userfields()->orderBy('name')->fetchAll();
|
||||
return $this->getDatabase()->userfields()->orderBy('name', 'COLLATE NOCASE')->fetchAll();
|
||||
}
|
||||
|
||||
public function GetAllValues($entity)
|
||||
@ -31,7 +31,7 @@ class UserfieldsService extends BaseService
|
||||
throw new \Exception('Entity does not exist or is not exposed');
|
||||
}
|
||||
|
||||
return $this->getDatabase()->userfield_values_resolved()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||
return $this->getDatabase()->userfield_values_resolved()->where('entity', $entity)->orderBy('name', 'COLLATE NOCASE')->fetchAll();
|
||||
}
|
||||
|
||||
public function GetEntities()
|
||||
@ -40,7 +40,7 @@ class UserfieldsService extends BaseService
|
||||
|
||||
$userentities = [];
|
||||
|
||||
foreach ($this->getDatabase()->userentities()->orderBy('name') as $userentity)
|
||||
foreach ($this->getDatabase()->userentities()->orderBy('name', 'COLLATE NOCASE') as $userentity)
|
||||
{
|
||||
$userentities[] = 'userentity-' . $userentity->name;
|
||||
}
|
||||
@ -65,7 +65,7 @@ class UserfieldsService extends BaseService
|
||||
throw new \Exception('Entity does not exist or is not exposed');
|
||||
}
|
||||
|
||||
return $this->getDatabase()->userfields()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||
return $this->getDatabase()->userfields()->where('entity', $entity)->orderBy('name', 'COLLATE NOCASE')->fetchAll();
|
||||
}
|
||||
|
||||
public function GetValues($entity, $objectId)
|
||||
@ -75,7 +75,7 @@ class UserfieldsService extends BaseService
|
||||
throw new \Exception('Entity does not exist or is not exposed');
|
||||
}
|
||||
|
||||
$userfields = $this->getDatabase()->userfield_values_resolved()->where('entity = :1 AND object_id = :2', $entity, $objectId)->orderBy('name')->fetchAll();
|
||||
$userfields = $this->getDatabase()->userfield_values_resolved()->where('entity = :1 AND object_id = :2', $entity, $objectId)->orderBy('name', 'COLLATE NOCASE')->fetchAll();
|
||||
$userfieldKeyValuePairs = [];
|
||||
|
||||
foreach ($userfields as $userfield)
|
||||
|
@ -177,7 +177,7 @@
|
||||
<label for="assignment_config">{{ $__t('Assign to') }}</label>
|
||||
<select required
|
||||
multiple
|
||||
class="custom-control custom-select input-group-chore-assignment-type selectpicker"
|
||||
class="form-control input-group-chore-assignment-type selectpicker"
|
||||
id="assignment_config"
|
||||
name="assignment_config"
|
||||
data-actions-Box="true"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
@php if(!isset($value)) { $value = 1; } @endphp
|
||||
@php if(empty($min)) { $min = 0; } @endphp
|
||||
@php if(empty($max)) { $max = 999999; } @endphp
|
||||
@php if(!isset($max)) { $max = ''; } @endphp
|
||||
@php if(empty($decimals)) { $decimals = 0; } @endphp
|
||||
@php if(empty($hint)) { $hint = ''; } @endphp
|
||||
@php if(empty($hintId)) { $hintId = ''; } @endphp
|
||||
@ -20,7 +20,8 @@
|
||||
|
||||
<div id="group-{{ $id }}"
|
||||
class="form-group {{ $additionalGroupCssClasses }}">
|
||||
<label for="{{ $id }}">
|
||||
<label class="w-100"
|
||||
for="{{ $id }}">
|
||||
{{ $__t($label) }}
|
||||
@if(!empty($hint) || !empty($hintId))
|
||||
<i id="{{ $hintId }}"
|
||||
@ -31,7 +32,7 @@
|
||||
{!! $additionalHtmlContextHelp !!}
|
||||
@if(!empty($contextInfoId))
|
||||
<span id="{{ $contextInfoId }}"
|
||||
class="small text-muted"></span>
|
||||
class="small text-muted float-right mt-1"></span>
|
||||
@endif
|
||||
</label>
|
||||
<div class="input-group">
|
||||
@ -46,8 +47,10 @@
|
||||
@endif
|
||||
value="{{ $value }}"
|
||||
min="{{ number_format($min, $decimals, '.', '') }}"
|
||||
@if(!empty($max))
|
||||
max="{{ number_format($max, $decimals, '.', '') }}"
|
||||
step="@if($decimals == 0){{1}}@else{{'.' . str_repeat('0', $userSettings['stock_decimal_places_amounts'] - 1) . '1'}}@endif"
|
||||
@endif
|
||||
step="@if($decimals == 0){{1}}@else{{'.' . str_repeat('0', $decimals - 1) . '1'}}@endif"
|
||||
data-decimals="{{ $decimals }}"
|
||||
@if($isRequired)
|
||||
required
|
||||
|
@ -101,7 +101,7 @@
|
||||
<div class="form-group">
|
||||
<label for="{{ $userfield->name }}">{{ $userfield->caption }}</label>
|
||||
<select multiple
|
||||
class="custom-control custom-select userfield-input selectpicker"
|
||||
class="form-control userfield-input selectpicker"
|
||||
data-userfield-name="{{ $userfield->name }}"
|
||||
data-actions-Box="true"
|
||||
data-live-search="true">
|
||||
|
@ -90,6 +90,11 @@
|
||||
value="1">
|
||||
@endif
|
||||
|
||||
@include('components.userfieldsform', array(
|
||||
'userfields' => $userfields,
|
||||
'entity' => 'product_barcodes'
|
||||
))
|
||||
|
||||
<button id="save-barcode-button"
|
||||
class="btn btn-success">{{ $__t('Save') }}</button>
|
||||
|
||||
|
@ -469,6 +469,10 @@
|
||||
@endif
|
||||
<th>{{ $__t('Quantity unit') }}</th>
|
||||
<th>{{ $__t('Amount') }}</th>
|
||||
|
||||
@include('components.userfields_thead', array(
|
||||
'userfields' => $productBarcodeUserfields
|
||||
))
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="d-none">
|
||||
@ -510,6 +514,11 @@
|
||||
<span class="locale-number locale-number-quantity-amount">{{ $barcode->amount }}</span>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
@include('components.userfields_tbody', array(
|
||||
'userfields' => $productBarcodeUserfields,
|
||||
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($productBarcodeUserfieldValues, 'object_id', $barcode->id)
|
||||
))
|
||||
</tr>
|
||||
@endif
|
||||
@endforeach
|
||||
@ -595,7 +604,7 @@
|
||||
@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, $quConversion->factor, FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name) }}
|
||||
{!! $__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>', FindObjectInArrayByPropertyValue($quantityunits, 'id', $quConversion->to_qu_id)->name) !!}
|
||||
</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
@ -103,6 +103,8 @@
|
||||
<div class="title-related-links">
|
||||
<h4>
|
||||
{{ $__t('Default conversions') }}
|
||||
<small id="qu-conversion-headline-info"
|
||||
class="text-muted font-italic"></small>
|
||||
</h4>
|
||||
<button class="btn btn-outline-dark d-md-none mt-2 float-right order-1 order-md-3"
|
||||
type="button"
|
||||
@ -119,9 +121,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 id="qu-conversion-headline-info"
|
||||
class="text-muted font-italic"></h5>
|
||||
|
||||
<table id="qu-conversions-table"
|
||||
class="table table-sm table-striped nowrap w-100">
|
||||
<thead>
|
||||
@ -154,7 +153,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ $defaultQuConversion->factor }}
|
||||
<span class="locale-number locale-number-quantity-amount">{{ $defaultQuConversion->factor }}</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ FindObjectInArrayByPropertyValue($quantityUnits, 'id', $defaultQuConversion->to_qu_id)->name }}
|
||||
|
@ -187,7 +187,7 @@
|
||||
$productQuConversions = FindAllObjectsInArrayByPropertyValue($quantityUnitConversionsResolved, 'product_id', $product->id);
|
||||
$productQuConversions = FindAllObjectsInArrayByPropertyValue($productQuConversions, 'from_qu_id', $product->qu_id_stock);
|
||||
$productQuConversion = FindObjectInArrayByPropertyValue($productQuConversions, 'to_qu_id', $recipePosition->qu_id);
|
||||
if ($productQuConversion)
|
||||
if ($productQuConversion && $recipePosition->only_check_single_unit_in_stock == 0)
|
||||
{
|
||||
$recipePosition->amount = $recipePosition->amount * $productQuConversion->factor;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@
|
||||
$productQuConversions = FindAllObjectsInArrayByPropertyValue($quantityUnitConversionsResolved, 'product_id', $product->id);
|
||||
$productQuConversions = FindAllObjectsInArrayByPropertyValue($productQuConversions, 'from_qu_id', $product->qu_id_stock);
|
||||
$productQuConversion = FindObjectInArrayByPropertyValue($productQuConversions, 'to_qu_id', $selectedRecipePosition->qu_id);
|
||||
if ($productQuConversion)
|
||||
if ($productQuConversion && $selectedRecipePosition->only_check_single_unit_in_stock == 0)
|
||||
{
|
||||
$selectedRecipePosition->recipe_amount = $selectedRecipePosition->recipe_amount * $productQuConversion->factor;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@
|
||||
<div class="related-links collapse d-md-flex order-2 width-xs-sm-100"
|
||||
id="related-links">
|
||||
<div class="my-auto float-right">
|
||||
<select class="custom-control custom-select"
|
||||
<select class="custom-control custom-select custom-select-sm"
|
||||
id="selected-shopping-list">
|
||||
@foreach($shoppingLists as $shoppingList)
|
||||
<option @if($shoppingList->id == $selectedShoppingListId) selected="selected" @endif value="{{ $shoppingList->id }}">{{ $shoppingList->name }}</option>
|
||||
@ -190,6 +190,9 @@
|
||||
@include('components.userfields_thead', array(
|
||||
'userfields' => $userfields
|
||||
))
|
||||
@include('components.userfields_thead', array(
|
||||
'userfields' => $productUserfields
|
||||
))
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
@ -259,6 +262,10 @@
|
||||
|
||||
@include('components.userfields_tbody', array(
|
||||
'userfields' => $userfields,
|
||||
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $listItem->id)
|
||||
))
|
||||
@include('components.userfields_tbody', array(
|
||||
'userfields' => $productUserfields,
|
||||
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $listItem->product_id)
|
||||
))
|
||||
|
||||
|
@ -43,6 +43,11 @@
|
||||
<div class="invalid-feedback">{{ $__t('A name is required') }}</div>
|
||||
</div>
|
||||
|
||||
@include('components.userfieldsform', array(
|
||||
'userfields' => $userfields,
|
||||
'entity' => 'shopping_lists'
|
||||
))
|
||||
|
||||
<button id="save-shopping-list-button"
|
||||
class="btn btn-success">{{ $__t('Save') }}</button>
|
||||
|
||||
|
@ -84,6 +84,11 @@
|
||||
name="note">@if($mode == 'edit'){{ $listItem->note }}@endif</textarea>
|
||||
</div>
|
||||
|
||||
@include('components.userfieldsform', array(
|
||||
'userfields' => $userfields,
|
||||
'entity' => 'shopping_list'
|
||||
))
|
||||
|
||||
<button id="save-shoppinglist-button"
|
||||
class="btn btn-success">{{ $__t('Save') }}</button>
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
<div class="row collapse d-md-flex"
|
||||
id="table-filter-row">
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="col-xs-12 col-md-6 col-xl-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
@ -45,7 +45,7 @@
|
||||
placeholder="{{ $__t('Search') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="col-xs-12 col-md-6 col-xl-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('Product') }}</span>
|
||||
@ -59,8 +59,50 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('Transaction type') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="transaction-type-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($transactionTypes as $transactionType)
|
||||
<option value="{{ $transactionType }}">{{ $__t($transactionType) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('Location') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="location-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($locations as $location)
|
||||
<option value="{{ $location->id }}">{{ $location->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('User') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="user-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($users as $user)
|
||||
<option value="{{ $user->id }}">{{ $user->display_name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="float-right">
|
||||
<div class="float-right mt-1">
|
||||
<a id="clear-filter-button"
|
||||
class="btn btn-sm btn-outline-info"
|
||||
href="#">
|
||||
|
@ -8,17 +8,98 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2 class="title">@yield('title')</h2>
|
||||
<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="#table-filter-row">
|
||||
<i class="fas fa-filter"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="row">
|
||||
<div class="row collapse d-md-flex"
|
||||
id="table-filter-row">
|
||||
<div class="col-xs-12 col-md-6 col-xl-2">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
||||
</div>
|
||||
<input type="text"
|
||||
id="search"
|
||||
class="form-control"
|
||||
placeholder="{{ $__t('Search') }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('Product') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="product-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($products as $product)
|
||||
<option value="{{ $product->id }}">{{ $product->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('Transaction type') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="transaction-type-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($transactionTypes as $transactionType)
|
||||
<option value="{{ $transactionType }}">{{ $__t($transactionType) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fas fa-filter"></i> {{ $__t('User') }}</span>
|
||||
</div>
|
||||
<select class="custom-control custom-select"
|
||||
id="user-filter">
|
||||
<option value="all">{{ $__t('All') }}</option>
|
||||
@foreach($users as $user)
|
||||
<option value="{{ $user->id }}">{{ $user->display_name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<table id="journal-summary-table"
|
||||
<div class="float-right mt-1">
|
||||
<a id="clear-filter-button"
|
||||
class="btn btn-sm btn-outline-info"
|
||||
href="#">
|
||||
{{ $__t('Clear filter') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col">
|
||||
<table id="stock-journal-summary-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('Hide/view columns') }}"
|
||||
data-table-selector="#stock-journal-summary-table"
|
||||
href="#"><i class="fas fa-eye"></i></a>
|
||||
</th>
|
||||
<th>{{ $__t('Product') }}</th>
|
||||
<th>{{ $__t('Transaction type') }}</th>
|
||||
<th>{{ $__t('User') }}</th>
|
||||
@ -28,6 +109,7 @@
|
||||
<tbody class="d-none">
|
||||
@foreach($entries as $journalEntry)
|
||||
<tr>
|
||||
<td class="fit-content border-right"></td>
|
||||
<td>
|
||||
{{ $journalEntry->product_name }}
|
||||
</td>
|
||||
|
@ -84,7 +84,7 @@
|
||||
'id' => 'stock_default_purchase_amount',
|
||||
'additionalAttributes' => 'data-setting-key="stock_default_purchase_amount"',
|
||||
'label' => 'Default amount for purchase',
|
||||
'min' => 0,
|
||||
'min' => '0.',
|
||||
'decimals' => $userSettings['stock_decimal_places_amounts'],
|
||||
'additionalCssClasses' => 'user-setting-control locale-number-input locale-number-quantity-amount',
|
||||
))
|
||||
|
Loading…
x
Reference in New Issue
Block a user