mirror of
https://github.com/grocy/grocy.git
synced 2026-10-17 05:14:20 +02:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41206cb901 | ||
|
|
80f68d4e93 | ||
|
|
f1e92931c9 | ||
|
|
7d15c46bbd | ||
|
|
41f150fc95 | ||
|
|
e6a1c11775 | ||
|
|
da8be4d73f | ||
|
|
1d5730523d | ||
|
|
10b7b446cf | ||
|
|
3c8edb515c | ||
|
|
85dc601b37 | ||
|
|
e83699b346 | ||
|
|
b6ee94341a | ||
|
|
0cf4d557af | ||
|
|
020841117f | ||
|
|
d9889fd157 |
6
app.php
6
app.php
|
|
@ -46,6 +46,7 @@ try
|
|||
}
|
||||
catch (\Grocy\Helpers\EInvalidConfig $ex)
|
||||
{
|
||||
http_response_code(500);
|
||||
exit('Invalid setting in config.php: ' . $ex->getMessage());
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +61,11 @@ if (!file_exists($viewcachePath))
|
|||
// The version changed (so when an update was done)
|
||||
// GROCY_BASE_URL OR GROCY_BASE_PATH changed
|
||||
$hash = hash('sha256', file_get_contents(__DIR__ . '/version.json') . GROCY_BASE_URL . GROCY_BASE_PATH);
|
||||
if (GROCY_MODE === 'dev')
|
||||
{
|
||||
// For dev mode use routes.php to track changes
|
||||
$hash = hash('sha256', file_get_contents(__DIR__ . '/routes.php'));
|
||||
}
|
||||
$hashCacheFile = $viewcachePath . "/$hash.txt";
|
||||
if (!file_exists($hashCacheFile))
|
||||
{
|
||||
|
|
|
|||
17
changelog/83_4.7.1_2026-09-04.md
Normal file
17
changelog/83_4.7.1_2026-09-04.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
### Stock
|
||||
|
||||
- Fixed that certain fields were not copied when copying a product
|
||||
|
||||
### Calendar
|
||||
|
||||
- Fixed that the iCal export was broken (any shared `https://<Grocy>/api/calendar/ical?secret=xxx`-link always returned `401 Unauthorized`)
|
||||
|
||||
### General
|
||||
|
||||
- Optimized that table dropdown filters now search accent insensitive
|
||||
- Fixed that it wasn't possible to log in using passwords containing non-latin characters
|
||||
|
||||
### API
|
||||
|
||||
- New API endpoint `/stock/products/{productId}/copy` (to copy a product)
|
||||
- Fixed that API key authentication did not work when running Grocy in a subdirectory
|
||||
57
changelog/84_UNRELEASED_xxxx-xx-xx.md
Normal file
57
changelog/84_UNRELEASED_xxxx-xx-xx.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
> ⚠️ xxxBREAKING CHANGESxxx
|
||||
|
||||
> ❗ xxxImportant upgrade informationXXX
|
||||
|
||||
> 💡 xxxMinor upgrade informationXXX
|
||||
|
||||
### New Feature: xxxx
|
||||
|
||||
- xxx
|
||||
|
||||
### Stock
|
||||
|
||||
- xxx
|
||||
|
||||
### Shopping list
|
||||
|
||||
- xxx
|
||||
|
||||
### Recipes
|
||||
|
||||
- xxx
|
||||
|
||||
### Meal plan
|
||||
|
||||
- xxx
|
||||
|
||||
### Chores
|
||||
|
||||
- xxx
|
||||
|
||||
### Calendar
|
||||
|
||||
- xxx
|
||||
|
||||
### Tasks
|
||||
|
||||
- xxx
|
||||
|
||||
### Batteries
|
||||
|
||||
- xxx
|
||||
|
||||
### Equipment
|
||||
|
||||
- xxx
|
||||
|
||||
### Userfields
|
||||
|
||||
- xxx
|
||||
|
||||
### General
|
||||
|
||||
- xxx
|
||||
|
||||
### API
|
||||
|
||||
- The API endpoints `/stock/products/{productId}/open` and `/stock/products/by-barcode/{barcode}/open` now support a new (optional) `location_id` request body parameter (to only open stock entries at that location)
|
||||
34
composer.lock
generated
34
composer.lock
generated
|
|
@ -1001,7 +1001,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/bus",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/bus.git",
|
||||
|
|
@ -1054,7 +1054,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/collections.git",
|
||||
|
|
@ -1114,7 +1114,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/conditionable",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/conditionable.git",
|
||||
|
|
@ -1160,7 +1160,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/container",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/container.git",
|
||||
|
|
@ -1222,7 +1222,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
|
|
@ -1270,7 +1270,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/events",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/events.git",
|
||||
|
|
@ -1325,7 +1325,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/filesystem",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/filesystem.git",
|
||||
|
|
@ -1392,7 +1392,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/macroable",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/macroable.git",
|
||||
|
|
@ -1438,7 +1438,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/pipeline",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/pipeline.git",
|
||||
|
|
@ -1490,7 +1490,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/reflection",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/reflection.git",
|
||||
|
|
@ -1541,7 +1541,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
|
|
@ -1621,7 +1621,7 @@
|
|||
},
|
||||
{
|
||||
"name": "illuminate/view",
|
||||
"version": "v12.68.0",
|
||||
"version": "v12.69.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/view.git",
|
||||
|
|
@ -3065,16 +3065,16 @@
|
|||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.15.2",
|
||||
"version": "4.15.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470"
|
||||
"reference": "3675bf6baac66b07032575b7bef4200b60b7974b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/e12cb05ca2a14e8f459d019e87a31dc915b80470",
|
||||
"reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/3675bf6baac66b07032575b7bef4200b60b7974b",
|
||||
"reference": "3675bf6baac66b07032575b7bef4200b60b7974b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3177,7 +3177,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-05-22T08:00:12+00:00"
|
||||
"time": "2026-09-01T17:11:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/clock",
|
||||
|
|
|
|||
|
|
@ -555,6 +555,12 @@ class StockApiController extends BaseApiController
|
|||
throw new \Exception('An amount is required');
|
||||
}
|
||||
|
||||
$locationId = null;
|
||||
if (array_key_exists('location_id', $requestBody) && !empty($requestBody['location_id']) && is_numeric($requestBody['location_id']))
|
||||
{
|
||||
$locationId = $requestBody['location_id'];
|
||||
}
|
||||
|
||||
$specificStockEntryId = 'default';
|
||||
if (array_key_exists('stock_entry_id', $requestBody) && !empty($requestBody['stock_entry_id']))
|
||||
{
|
||||
|
|
@ -568,7 +574,7 @@ class StockApiController extends BaseApiController
|
|||
}
|
||||
|
||||
$transactionId = null;
|
||||
$transactionId = StockService::GetInstance()->OpenProduct($args['productId'], $requestBody['amount'], $specificStockEntryId, $transactionId, $allowSubproductSubstitution);
|
||||
$transactionId = StockService::GetInstance()->OpenProduct($args['productId'], $requestBody['amount'], $locationId, $specificStockEntryId, $transactionId, $allowSubproductSubstitution);
|
||||
$args['transactionId'] = $transactionId;
|
||||
return $this->StockTransactions($request, $response, $args);
|
||||
}
|
||||
|
|
@ -648,7 +654,7 @@ class StockApiController extends BaseApiController
|
|||
$allowSubproductSubstitution = true;
|
||||
}
|
||||
|
||||
return $this->FilteredApiResponse($response, StockService::GetInstance()->GetProductStockEntries($args['productId'], false, $allowSubproductSubstitution), $request->getQueryParams());
|
||||
return $this->FilteredApiResponse($response, StockService::GetInstance()->GetProductStockEntries($args['productId'], null, false, $allowSubproductSubstitution), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function LocationStockEntries(Request $request, Response $response, array $args)
|
||||
|
|
@ -926,4 +932,25 @@ class StockApiController extends BaseApiController
|
|||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function CopyProduct(Request $request, Response $response, array $args)
|
||||
{
|
||||
User::CheckPermission($request, User::PERMISSION_STOCK_EDIT);
|
||||
|
||||
try
|
||||
{
|
||||
if (filter_var($args['productId'], FILTER_VALIDATE_INT) === false)
|
||||
{
|
||||
throw new \Exception('Provided {productId} is not a valid integer');
|
||||
}
|
||||
|
||||
return $this->ApiResponse($response, [
|
||||
'created_object_id' => StockService::GetInstance()->CopyProduct($args['productId'])
|
||||
]);
|
||||
}
|
||||
catch (\Exception $ex)
|
||||
{
|
||||
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class ExceptionController extends BaseApiController
|
|||
}
|
||||
|
||||
$response = $this->ResponseFactory->createResponse();
|
||||
$isApiRoute = string_starts_with($request->getUri()->getPath(), '/api/');
|
||||
$isApiRoute = str_contains($request->getUri()->getPath(), '/api/');
|
||||
|
||||
if (!defined('GROCY_AUTHENTICATED'))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2255,6 +2255,10 @@
|
|||
"allow_subproduct_substitution": {
|
||||
"type": "boolean",
|
||||
"description": "`true` when any in stock sub product should be used when the given product is a parent product and currently not in stock"
|
||||
},
|
||||
"location_id": {
|
||||
"type": "integer",
|
||||
"description": "A valid location id (if supplied, only stock at the given location is considered, if ommitted, stock of any location is considered)"
|
||||
}
|
||||
},
|
||||
"example": {
|
||||
|
|
@ -2333,6 +2337,53 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"/stock/products/{productId}/copy": {
|
||||
"post": {
|
||||
"summary": "Copies a product",
|
||||
"tags": [
|
||||
"Stock"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "productId",
|
||||
"required": true,
|
||||
"description": "A valid product id of the product to copy",
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The operation was successful",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_object_id": {
|
||||
"type": "integer",
|
||||
"description": "The id of the created product"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "The operation was not successful (possible errors are: Invalid product id)",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error400"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/stock/products/{productIdToKeep}/merge/{productIdToRemove}": {
|
||||
"post": {
|
||||
"summary": "Merges two products into one",
|
||||
|
|
@ -2552,7 +2603,7 @@
|
|||
},
|
||||
"allow_subproduct_substitution": {
|
||||
"type": "boolean",
|
||||
"description": "`rue` when any in stock sub product should be used when the given product is a parent product and currently not in stock"
|
||||
"description": "`true` when any in stock sub product should be used when the given product is a parent product and currently not in stock"
|
||||
}
|
||||
},
|
||||
"example": {
|
||||
|
|
@ -2775,7 +2826,11 @@
|
|||
},
|
||||
"allow_subproduct_substitution": {
|
||||
"type": "boolean",
|
||||
"description": "`rue` when any in stock sub product should be used when the given product is a parent product and currently not in stock"
|
||||
"description": "`true` when any in stock sub product should be used when the given product is a parent product and currently not in stock"
|
||||
},
|
||||
"location_id": {
|
||||
"type": "integer",
|
||||
"description": "A valid location id (if supplied, only stock at the given location is considered, if ommitted, stock of any location is considered)"
|
||||
}
|
||||
},
|
||||
"example": {
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ class PrerequisiteChecker
|
|||
{
|
||||
public function checkRequirements()
|
||||
{
|
||||
self::checkForPhpVersion();
|
||||
self::checkForConfigFile();
|
||||
self::checkForConfigDistFile();
|
||||
self::checkForComposer();
|
||||
self::checkForPhpExtensions();
|
||||
self::checkForSqliteVersion();
|
||||
self::CheckPhpVersion();
|
||||
self::CheckConfigFile();
|
||||
self::CheckConfigDistFile();
|
||||
self::CheckComposer();
|
||||
self::CheckPhpExtensions();
|
||||
self::CheckSqliteVersion();
|
||||
}
|
||||
|
||||
private function checkForComposer()
|
||||
private function CheckComposer()
|
||||
{
|
||||
if (!file_exists(__DIR__ . '/../packages/autoload.php'))
|
||||
{
|
||||
|
|
@ -35,7 +35,7 @@ class PrerequisiteChecker
|
|||
}
|
||||
}
|
||||
|
||||
private function checkForConfigDistFile()
|
||||
private function CheckConfigDistFile()
|
||||
{
|
||||
if (!file_exists(__DIR__ . '/../config-dist.php'))
|
||||
{
|
||||
|
|
@ -43,7 +43,7 @@ class PrerequisiteChecker
|
|||
}
|
||||
}
|
||||
|
||||
private function checkForConfigFile()
|
||||
private function CheckConfigFile()
|
||||
{
|
||||
if (!file_exists(GROCY_DATAPATH . '/config.php'))
|
||||
{
|
||||
|
|
@ -51,7 +51,7 @@ class PrerequisiteChecker
|
|||
}
|
||||
}
|
||||
|
||||
private function checkForPhpExtensions()
|
||||
private function CheckPhpExtensions()
|
||||
{
|
||||
$loadedExtensions = get_loaded_extensions();
|
||||
foreach (REQUIRED_PHP_EXTENSIONS as $extension)
|
||||
|
|
@ -63,16 +63,16 @@ class PrerequisiteChecker
|
|||
}
|
||||
}
|
||||
|
||||
private function checkForSqliteVersion()
|
||||
private function CheckSqliteVersion()
|
||||
{
|
||||
$sqliteVersion = self::getSqlVersionAsString();
|
||||
$sqliteVersion = self::GetSqlVersion();
|
||||
if (version_compare($sqliteVersion, REQUIRED_SQLITE_VERSION, '<'))
|
||||
{
|
||||
throw new ERequirementNotMet('SQLite ' . REQUIRED_SQLITE_VERSION . ' is required, however you are running ' . $sqliteVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private function checkForPhpVersion()
|
||||
private function CheckPhpVersion()
|
||||
{
|
||||
$phpVersion = phpversion();
|
||||
if (version_compare($phpVersion, REQUIRED_PHP_VERSION, '<'))
|
||||
|
|
@ -81,7 +81,7 @@ class PrerequisiteChecker
|
|||
}
|
||||
}
|
||||
|
||||
private function getSqlVersionAsString()
|
||||
private function GetSqlVersion(): string
|
||||
{
|
||||
$dbh = new \PDO('sqlite::memory:');
|
||||
return $dbh->query('select sqlite_version()')->fetch()[0];
|
||||
|
|
|
|||
|
|
@ -2393,9 +2393,6 @@ msgstr[1] "%s години"
|
|||
msgid "Display product"
|
||||
msgstr "Показване на продукта"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Копирайте рецептата"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Копие от %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2360,9 +2360,6 @@ msgstr[1] "%s anys"
|
|||
msgid "Display product"
|
||||
msgstr "Mostrar producte"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copiar recepta"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copia de %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
# Radim Kabeláč <radim.ekk@gmail.com>, 2020
|
||||
# Jaroslav Lichtblau <l10n@lichtblau.cz>, 2020
|
||||
# Jarda Tesar <intossh@gmail.com>, 2021
|
||||
# Pavel Paseka, 2026
|
||||
# Michal Petříček <michal@petricek.org>, 2026
|
||||
# Pavel Paseka, 2026
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"PO-Revision-Date: 2019-05-01 17:42+0000\n"
|
||||
"Last-Translator: Michal Petříček <michal@petricek.org>, 2026\n"
|
||||
"Last-Translator: Pavel Paseka, 2026\n"
|
||||
"Language-Team: Czech (https://app.transifex.com/grocy/teams/93189/cs/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
|
@ -721,7 +721,7 @@ msgid "Are you sure you want to delete product group \"%s\"?"
|
|||
msgstr "Odstranit skupinu produktů „%s“?"
|
||||
|
||||
msgid "Remember Me"
|
||||
msgstr ""
|
||||
msgstr "Zapamatuj si mne"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "Stav"
|
||||
|
|
@ -1831,7 +1831,7 @@ msgid "Clear filter"
|
|||
msgstr "Smazat filtr"
|
||||
|
||||
msgid "Permissions"
|
||||
msgstr ""
|
||||
msgstr "Oprávnění"
|
||||
|
||||
msgid "Are you sure you want to remove full permissions for yourself?"
|
||||
msgstr "Opravdu chcete odstranit všechna svoje oprávnění?"
|
||||
|
|
@ -2444,9 +2444,6 @@ msgstr[3] "%s let"
|
|||
msgid "Display product"
|
||||
msgstr "Zobrazit produkt"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Vytvořit kopii receptu"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "%s (Kopie)"
|
||||
|
||||
|
|
@ -2911,25 +2908,25 @@ msgstr[2] "Balení"
|
|||
msgstr[3] "Balení"
|
||||
|
||||
msgid "Manage user sessions"
|
||||
msgstr ""
|
||||
msgstr "Správa přihlášených uživatelů"
|
||||
|
||||
msgid "Sessions"
|
||||
msgstr ""
|
||||
msgstr "Přihlášení"
|
||||
|
||||
msgid "Token type"
|
||||
msgstr ""
|
||||
msgstr "Způsob přihlášení"
|
||||
|
||||
msgid "Token hash"
|
||||
msgstr ""
|
||||
msgstr "Otisk přístupového kódu"
|
||||
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Přístup přes"
|
||||
|
||||
msgid "This session"
|
||||
msgstr ""
|
||||
msgstr "Toto přihlášení"
|
||||
|
||||
msgid "Are you sure you want to delete the selected session?"
|
||||
msgstr ""
|
||||
msgstr "Opravdu chcete zrušit vybrané přihlášení?"
|
||||
|
||||
msgid "Last access"
|
||||
msgstr ""
|
||||
msgstr "Poslední přístup"
|
||||
|
|
|
|||
|
|
@ -2367,9 +2367,6 @@ msgstr[1] "%s år"
|
|||
msgid "Display product"
|
||||
msgstr "Vis vare"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopier opskrift"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopi af %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2410,9 +2410,6 @@ msgstr[1] "%s Jahre"
|
|||
msgid "Display product"
|
||||
msgstr "Produkt anzeigen"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Rezept kopieren"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopie von %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2315,9 +2315,6 @@ msgstr[1] "%sχρόνια"
|
|||
msgid "Display product"
|
||||
msgstr "Προβολή προϊόντος"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Αντιγραφή συνταγής"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2370,9 +2370,6 @@ msgstr[1] "%s years"
|
|||
msgid "Display product"
|
||||
msgstr "Display product"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copy recipe"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copy of %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2450,9 +2450,6 @@ msgstr[2] "%s años"
|
|||
msgid "Display product"
|
||||
msgstr "Mostrar producto"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copiar receta"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copia de %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2361,9 +2361,6 @@ msgstr[1] "%s aastat"
|
|||
msgid "Display product"
|
||||
msgstr "Näita toodet"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopeeri retsept"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "%s Koopia"
|
||||
|
||||
|
|
|
|||
|
|
@ -2383,9 +2383,6 @@ msgstr[1] "%s vuotta"
|
|||
msgid "Display product"
|
||||
msgstr "Näytä tuote"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopioi resepti"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopio nimikkeestä %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2473,9 +2473,6 @@ msgstr[2] "%s ans"
|
|||
msgid "Display product"
|
||||
msgstr "Afficher le produit"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copier la recette"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copie de %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -700,7 +700,7 @@ msgid "Are you sure you want to delete product group \"%s\"?"
|
|||
msgstr "למחוק את קבוצת המוצרים „%s”?"
|
||||
|
||||
msgid "Remember Me"
|
||||
msgstr ""
|
||||
msgstr "לזכור אותי"
|
||||
|
||||
msgid "Status"
|
||||
msgstr "מצב"
|
||||
|
|
@ -1782,7 +1782,7 @@ msgid "Clear filter"
|
|||
msgstr "לבטל את הסינון"
|
||||
|
||||
msgid "Permissions"
|
||||
msgstr ""
|
||||
msgstr "הרשאה"
|
||||
|
||||
msgid "Are you sure you want to remove full permissions for yourself?"
|
||||
msgstr "להסיר את מלוא ההרשאות לעצמך?"
|
||||
|
|
@ -2375,9 +2375,6 @@ msgstr[2] "%s שנים"
|
|||
msgid "Display product"
|
||||
msgstr "הצגת מוצר"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "העתקת מתכון"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "עותק של %s"
|
||||
|
||||
|
|
@ -2820,25 +2817,25 @@ msgstr[2] "אריזות"
|
|||
msgstr[3] "אריזות"
|
||||
|
||||
msgid "Manage user sessions"
|
||||
msgstr ""
|
||||
msgstr "ניהול הפעלות משתמשים"
|
||||
|
||||
msgid "Sessions"
|
||||
msgstr ""
|
||||
msgstr "הפעלות"
|
||||
|
||||
msgid "Token type"
|
||||
msgstr ""
|
||||
msgstr "סוג אסימון"
|
||||
|
||||
msgid "Token hash"
|
||||
msgstr ""
|
||||
msgstr "גיבוב אסימון"
|
||||
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "לקוח"
|
||||
|
||||
msgid "This session"
|
||||
msgstr ""
|
||||
msgstr "ההפעלה הזאת"
|
||||
|
||||
msgid "Are you sure you want to delete the selected session?"
|
||||
msgstr ""
|
||||
msgstr "למחוק את ההפעלה הנבחרת?"
|
||||
|
||||
msgid "Last access"
|
||||
msgstr ""
|
||||
msgstr "גישה אחרונה"
|
||||
|
|
|
|||
|
|
@ -2384,9 +2384,6 @@ msgstr[1] "%s év"
|
|||
msgid "Display product"
|
||||
msgstr "Termék megjelenítése"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Recept másolás"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "%s másolata"
|
||||
|
||||
|
|
|
|||
|
|
@ -2472,9 +2472,6 @@ msgstr[2] "%s anni"
|
|||
msgid "Display product"
|
||||
msgstr "Visualizza prodotto"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copia ricetta"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copia di %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# 鳥山 陽平 <kagemomiji@gmail.com>, 2020
|
||||
# Cisco Benjamin <metallica@vivaldi.net>, 2020
|
||||
# Takuya Mizuguchi, 2024
|
||||
# pigmentblue15, 2025
|
||||
# pigmentblue15, 2026
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
|
|
@ -11,7 +11,7 @@ msgstr ""
|
|||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-05-01T17:59:17+00:00\n"
|
||||
"PO-Revision-Date: 2019-05-01 17:42+0000\n"
|
||||
"Last-Translator: pigmentblue15, 2025\n"
|
||||
"Last-Translator: pigmentblue15, 2026\n"
|
||||
"Language-Team: Japanese (https://app.transifex.com/grocy/teams/93189/ja/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
|
@ -76,7 +76,7 @@ msgid "Cheese"
|
|||
msgstr "チーズ"
|
||||
|
||||
msgid "Cold cuts"
|
||||
msgstr "コールドカット"
|
||||
msgstr "スライスハム"
|
||||
|
||||
msgid "Paprika"
|
||||
msgstr "パプリカ"
|
||||
|
|
|
|||
|
|
@ -2226,9 +2226,6 @@ msgstr[0] "%s年"
|
|||
msgid "Display product"
|
||||
msgstr "物品を表示"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "レシピをコピー"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "%sのコピー"
|
||||
|
||||
|
|
|
|||
|
|
@ -2233,9 +2233,6 @@ msgstr[0] "%s년"
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2446,9 +2446,6 @@ msgstr[3] "%smetų"
|
|||
msgid "Display product"
|
||||
msgstr "Rodyti produktą"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopijuoti receptą"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopijuoti iš %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2440,9 +2440,6 @@ msgstr[1] "%s jaren"
|
|||
msgid "Display product"
|
||||
msgstr "Toon product"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopieer recept"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopie van %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2376,9 +2376,6 @@ msgstr[1] "%s år"
|
|||
msgid "Display product"
|
||||
msgstr "Vis produkt"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopier oppskrift"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopi av %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2467,9 +2467,6 @@ msgstr[3] "%s lat"
|
|||
msgid "Display product"
|
||||
msgstr "Wyświetl produkt"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopiuj przepis"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopia %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2445,9 +2445,6 @@ msgstr[2] "%s anos"
|
|||
msgid "Display product"
|
||||
msgstr "Exibir produto"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Copiar receita"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Copiar de %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2321,9 +2321,6 @@ msgstr[2] ""
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2351,9 +2351,6 @@ msgstr[2] "%s ani"
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2463,9 +2463,6 @@ msgstr[3] "%s лет"
|
|||
msgid "Display product"
|
||||
msgstr "Показать продукт"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Копировать рецепт"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Копия %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2343,9 +2343,6 @@ msgstr[3] ""
|
|||
msgid "Display product"
|
||||
msgstr "Zobraziť výrobok"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2337,9 +2337,6 @@ msgstr[3] "%s let"
|
|||
msgid "Display product"
|
||||
msgstr "Prikaži izdelek"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopiraj recept"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopiraj %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2113,9 +2113,6 @@ msgstr[1] ""
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2395,9 +2395,6 @@ msgstr[1] "%s år"
|
|||
msgid "Display product"
|
||||
msgstr "Visa produkt"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Kopiera recept"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Kopia av %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2246,9 +2246,6 @@ msgstr[1] ""
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -2363,9 +2363,6 @@ msgstr[1] "%syıl"
|
|||
msgid "Display product"
|
||||
msgstr "Ürünü görüntüle"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Tarifi kopyala"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "%s'ın kopyası"
|
||||
|
||||
|
|
|
|||
|
|
@ -2388,9 +2388,6 @@ msgstr[3] "%s років"
|
|||
msgid "Display product"
|
||||
msgstr "Показати продукт"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "Копіювати рецепт"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "Копія %s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2222,9 +2222,6 @@ msgstr[0] "%s年"
|
|||
msgid "Display product"
|
||||
msgstr "显示产品"
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "复制菜谱"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr "复制%s"
|
||||
|
||||
|
|
|
|||
|
|
@ -2218,9 +2218,6 @@ msgstr[0] "%s 年"
|
|||
msgid "Display product"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy recipe"
|
||||
msgstr "複製食譜"
|
||||
|
||||
msgid "Copy of %s"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class ApiKeyAuthMiddleware extends BaseAuthMiddleware
|
|||
// Handling of special purpose API keys
|
||||
if (!$validApiKey)
|
||||
{
|
||||
if ($this->RouteName === 'calendar-ical')
|
||||
if ($this->GetRouteName($request) === 'calendar-ical')
|
||||
{
|
||||
if ($request->getQueryParam('secret') !== null && $apiKeyService->IsValidApiKey($request->getQueryParam('secret'), ApiKeyService::API_KEY_TYPE_SPECIAL_PURPOSE_CALENDAR_ICAL))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,17 +11,10 @@ use Slim\Routing\RouteContext;
|
|||
|
||||
abstract class BaseAuthMiddleware extends BaseMiddleware
|
||||
{
|
||||
protected ?string $RouteName = null;
|
||||
protected bool $IsApiRoute = false;
|
||||
|
||||
public function __invoke(Request $request, RequestHandler $handler): Response
|
||||
{
|
||||
$routeContext = RouteContext::fromRequest($request);
|
||||
$route = $routeContext->getRoute();
|
||||
$this->RouteName = $route->getName();
|
||||
$this->IsApiRoute = string_starts_with($request->getUri()->getPath(), '/api/');
|
||||
|
||||
if ($this->RouteName === 'root' || $this->RouteName === 'login')
|
||||
$routeName = $this->GetRouteName($request);
|
||||
if ($routeName === 'root' || $routeName === 'login')
|
||||
{
|
||||
// Root and Login routes are public/unauthenticated
|
||||
|
||||
|
|
@ -53,7 +46,7 @@ abstract class BaseAuthMiddleware extends BaseMiddleware
|
|||
define('GROCY_AUTHENTICATED', false);
|
||||
$response = $this->ResponseFactory->createResponse();
|
||||
|
||||
if ($this->IsApiRoute)
|
||||
if ($this->IsApiRoute($request))
|
||||
{
|
||||
return $response->withStatus(401);
|
||||
}
|
||||
|
|
@ -69,7 +62,7 @@ abstract class BaseAuthMiddleware extends BaseMiddleware
|
|||
define('GROCY_USER_USERNAME', $user->username);
|
||||
define('GROCY_USER_PICTURE_FILE_NAME', $user->picture_file_name);
|
||||
|
||||
return $response = $handler->handle($request);
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +115,16 @@ abstract class BaseAuthMiddleware extends BaseMiddleware
|
|||
}
|
||||
}
|
||||
|
||||
protected function GetRouteName(Request $request): ?string
|
||||
{
|
||||
return RouteContext::fromRequest($request)->getRoute()?->getName();
|
||||
}
|
||||
|
||||
protected function IsApiRoute(Request $request): bool
|
||||
{
|
||||
return string_starts_with(RouteContext::fromRequest($request)->getRoute()->getPattern(), '/api/');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $postParams
|
||||
* @return bool True/False if the provided credentials were valid
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class DefaultAuthMiddleware extends BaseAuthMiddleware
|
|||
{
|
||||
protected function AuthenticateRequest(Request $request)
|
||||
{
|
||||
if ($this->IsApiRoute)
|
||||
if ($this->IsApiRoute($request))
|
||||
{
|
||||
// Session cookie or API Key is ok
|
||||
$auth = new SessionAuthMiddleware($this->AppContainer, $this->ResponseFactory);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class ReverseProxyAuthMiddleware extends BaseAuthMiddleware
|
|||
define('GROCY_EXTERNALLY_MANAGED_AUTHENTICATION', true);
|
||||
|
||||
// Try to use regular API Key authentication (applies when the reverse proxy is configured to be bypassed for API routes)
|
||||
if ($this->IsApiRoute)
|
||||
if ($this->IsApiRoute($request))
|
||||
{
|
||||
$auth = new ApiKeyAuthMiddleware($this->AppContainer, $this->ResponseFactory);
|
||||
$user = $auth->AuthenticateRequest($request);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ try
|
|||
}
|
||||
catch (Grocy\Helpers\ERequirementNotMet $ex)
|
||||
{
|
||||
http_response_code(500);
|
||||
exit('Unable to run Grocy: ' . $ex->getMessage());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
$('#batteries-table tbody').removeClass("d-none");
|
||||
batteriesTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -17,17 +17,17 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
batteriesTable.search(value).draw();
|
||||
batteriesTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
batteriesTable.search("").draw();
|
||||
$("#show-disabled").prop('checked', false);
|
||||
});
|
||||
|
||||
$(document).on('click', '.battery-delete-button', function(e)
|
||||
$(document).on('click', '.battery-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-battery-name');
|
||||
var objectId = $(e.currentTarget).attr('data-battery-id');
|
||||
|
|
@ -45,16 +45,16 @@ $(document).on('click', '.battery-delete-button', function(e)
|
|||
}
|
||||
},
|
||||
closeButton: false,
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/batteries/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/batteries');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ $(document).on('click', '.battery-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#batteries-journal-table tbody').removeClass("d-none");
|
||||
batteriesJournalTable.columns.adjust().draw();
|
||||
|
||||
$("#battery-filter").on("change", function()
|
||||
$("#battery-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -23,7 +23,7 @@ $("#battery-filter").on("change", function()
|
|||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -31,10 +31,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
batteriesJournalTable.search(value).draw();
|
||||
batteriesJournalTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#battery-filter").val("all");
|
||||
|
|
@ -45,7 +45,7 @@ $("#clear-filter-button").on("click", function()
|
|||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#daterange-filter").on("change", function()
|
||||
$("#daterange-filter").on("change", function ()
|
||||
{
|
||||
UpdateUriParam("months", $(this).val());
|
||||
window.location.reload();
|
||||
|
|
@ -61,7 +61,7 @@ if (typeof GetUriParam("months") !== "undefined")
|
|||
$("#daterange-filter").val(GetUriParam("months"));
|
||||
}
|
||||
|
||||
$(document).on('click', '.undo-battery-execution-button', function(e)
|
||||
$(document).on('click', '.undo-battery-execution-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ $(document).on('click', '.undo-battery-execution-button', function(e)
|
|||
var chargeCycleId = $(e.currentTarget).attr('data-charge-cycle-id');
|
||||
|
||||
Grocy.Api.Post('batteries/charge-cycles/' + chargeCycleId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
element.closest("tr").addClass("text-muted");
|
||||
element.parent().siblings().find("span.name-anchor").addClass("text-strike-through").after("<br>" + __t("Undone on") + " " + moment().format("YYYY-MM-DD HH:mm:ss") + " <time class='timeago timeago-contextual' datetime='" + moment().format("YYYY-MM-DD HH:mm:ss") + "'></time>");
|
||||
|
|
@ -77,7 +77,7 @@ $(document).on('click', '.undo-battery-execution-button', function(e)
|
|||
RefreshContextualTimeago("#charge-cycle-" + chargeCycleId + "-row");
|
||||
toastr.success(__t("Charge cycle successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
$('#batteries-overview-table tbody').removeClass("d-none");
|
||||
batteriesOverviewTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -18,10 +18,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
batteriesOverviewTable.search(value).draw();
|
||||
batteriesOverviewTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#status-filter").val("all");
|
||||
|
|
@ -29,7 +29,7 @@ $("#clear-filter-button").on("click", function()
|
|||
batteriesOverviewTable.search("").draw();
|
||||
});
|
||||
|
||||
$("#status-filter").on("change", function()
|
||||
$("#status-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -40,17 +40,17 @@ $("#status-filter").on("change", function()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
batteriesOverviewTable.column(batteriesOverviewTable.colReorder.transpose(5)).search(value).draw();
|
||||
batteriesOverviewTable.column(batteriesOverviewTable.colReorder.transpose(5)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$(".status-filter-message").on("click", function()
|
||||
$(".status-filter-message").on("click", function ()
|
||||
{
|
||||
var value = $(this).data("status-filter");
|
||||
$("#status-filter").val(value);
|
||||
$("#status-filter").trigger("change");
|
||||
});
|
||||
|
||||
$(document).on('click', '.track-charge-cycle-button', function(e)
|
||||
$(document).on('click', '.track-charge-cycle-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -61,10 +61,10 @@ $(document).on('click', '.track-charge-cycle-button', function(e)
|
|||
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
|
||||
Grocy.Api.Post('batteries/' + batteryId + '/charge', { 'tracked_time': trackedTime },
|
||||
function()
|
||||
function ()
|
||||
{
|
||||
Grocy.Api.Get('batteries/' + batteryId,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var batteryRow = $('#battery-' + batteryId + '-row');
|
||||
var nextXDaysThreshold = moment().add($("#info-due-soon-batteries").data("next-x-days"), "days");
|
||||
|
|
@ -97,14 +97,14 @@ $(document).on('click', '.track-charge-cycle-button', function(e)
|
|||
RefreshContextualTimeago("#battery-" + batteryId + "-row");
|
||||
RefreshStatistics();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
|
|
@ -112,12 +112,12 @@ $(document).on('click', '.track-charge-cycle-button', function(e)
|
|||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.battery-grocycode-label-print', function(e)
|
||||
$(document).on('click', '.battery-grocycode-label-print', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var batteryId = $(e.currentTarget).attr('data-battery-id');
|
||||
Grocy.Api.Get('batteries/' + batteryId + '/printlabel', function(labelData)
|
||||
Grocy.Api.Get('batteries/' + batteryId + '/printlabel', function (labelData)
|
||||
{
|
||||
if (Grocy.Webhooks.labelprinter !== undefined)
|
||||
{
|
||||
|
|
@ -130,7 +130,7 @@ function RefreshStatistics()
|
|||
{
|
||||
var nextXDays = $("#info-due-soon-batteries").data("next-x-days");
|
||||
Grocy.Api.Get('batteries',
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var dueTodayCount = 0;
|
||||
var dueSoonCount = 0;
|
||||
|
|
@ -162,7 +162,7 @@ function RefreshStatistics()
|
|||
$("#info-due-soon-batteries").html('<span class="d-block d-md-none">' + dueSoonCount + ' <i class="fa-solid fa-clock"></i></span><span class="d-none d-md-block">' + __n(dueSoonCount, '%s battery is due to be charged', '%s batteries are due to be charged') + ' ' + __n(nextXDays, 'within the next day', 'within the next %s days'));
|
||||
$("#info-overdue-batteries").html('<span class="d-block d-md-none">' + overdueCount + ' <i class="fa-solid fa-times-circle"></i></span><span class="d-none d-md-block">' + __n(overdueCount, '%s battery is overdue to be charged', '%s batteries are overdue to be charged'));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#chores-table tbody').removeClass("d-none");
|
||||
choresTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,17 +16,17 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
choresTable.search(value).draw();
|
||||
choresTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
choresTable.search("").draw();
|
||||
$("#show-disabled").prop('checked', false);
|
||||
});
|
||||
|
||||
$(document).on('click', '.chore-delete-button', function(e)
|
||||
$(document).on('click', '.chore-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-chore-name');
|
||||
var objectId = $(e.currentTarget).attr('data-chore-id');
|
||||
|
|
@ -44,16 +44,16 @@ $(document).on('click', '.chore-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/chores/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/chores');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@ $(document).on('click', '.chore-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
@ -80,7 +80,7 @@ if (GetUriParam('include_disabled'))
|
|||
$("#show-disabled").prop('checked', true);
|
||||
}
|
||||
|
||||
$(".merge-chores-button").on("click", function(e)
|
||||
$(".merge-chores-button").on("click", function (e)
|
||||
{
|
||||
var choreId = $(e.currentTarget).attr("data-chore-id");
|
||||
$("#merge-chores-keep").val(choreId);
|
||||
|
|
@ -88,7 +88,7 @@ $(".merge-chores-button").on("click", function(e)
|
|||
$("#merge-chores-modal").modal("show");
|
||||
});
|
||||
|
||||
$("#merge-chores-save-button").on("click", function(e)
|
||||
$("#merge-chores-save-button").on("click", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -101,11 +101,11 @@ $("#merge-chores-save-button").on("click", function(e)
|
|||
var choreIdToRemove = $("#merge-chores-remove").val();
|
||||
|
||||
Grocy.Api.Post("chores/" + choreIdToKeep.toString() + "/merge/" + choreIdToRemove.toString(), {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/chores');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while merging', xhr.response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
$('#chores-journal-table tbody').removeClass("d-none");
|
||||
choresJournalTable.columns.adjust().draw();
|
||||
|
||||
$("#chore-filter").on("change", function()
|
||||
$("#chore-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -24,13 +24,13 @@ $("#chore-filter").on("change", function()
|
|||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#daterange-filter").on("change", function()
|
||||
$("#daterange-filter").on("change", function ()
|
||||
{
|
||||
UpdateUriParam("months", $(this).val());
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -38,10 +38,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
choresJournalTable.search(value).draw();
|
||||
choresJournalTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#daterange-filter").val("24");
|
||||
|
|
@ -66,7 +66,7 @@ if (typeof GetUriParam("months") !== "undefined")
|
|||
$("#daterange-filter").val(GetUriParam("months"));
|
||||
}
|
||||
|
||||
$(document).on('click', '.undo-chore-execution-button', function(e)
|
||||
$(document).on('click', '.undo-chore-execution-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ $(document).on('click', '.undo-chore-execution-button', function(e)
|
|||
var executionId = $(e.currentTarget).attr('data-execution-id');
|
||||
|
||||
Grocy.Api.Post('chores/executions/' + executionId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
element.closest("tr").addClass("text-muted");
|
||||
element.parent().siblings().find("span.name-anchor").addClass("text-strike-through").after("<br>" + __t("Undone on") + " " + moment().format("YYYY-MM-DD HH:mm:ss") + " <time class='timeago timeago-contextual' datetime='" + moment().format("YYYY-MM-DD HH:mm:ss") + "'></time>");
|
||||
|
|
@ -82,7 +82,7 @@ $(document).on('click', '.undo-chore-execution-button', function(e)
|
|||
RefreshContextualTimeago("#chore-execution-" + executionId + "-row");
|
||||
toastr.success(__t("Chore execution successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
$('#chores-overview-table tbody').removeClass("d-none");
|
||||
choresOverviewTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -19,10 +19,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
choresOverviewTable.search(value).draw();
|
||||
choresOverviewTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#status-filter").on("change", function()
|
||||
$("#status-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -33,10 +33,10 @@ $("#status-filter").on("change", function()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
choresOverviewTable.column(choresOverviewTable.colReorder.transpose(5)).search(value).draw();
|
||||
choresOverviewTable.column(choresOverviewTable.colReorder.transpose(5)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function()
|
||||
$("#user-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -47,7 +47,7 @@ $("#user-filter").on("change", function()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
choresOverviewTable.column(choresOverviewTable.colReorder.transpose(6)).search(value).draw();
|
||||
choresOverviewTable.column(choresOverviewTable.colReorder.transpose(6)).search(value.accentNeutralise()).draw();
|
||||
|
||||
if (value)
|
||||
{
|
||||
|
|
@ -55,7 +55,7 @@ $("#user-filter").on("change", function()
|
|||
}
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#status-filter").val("all");
|
||||
|
|
@ -66,21 +66,21 @@ $("#clear-filter-button").on("click", function()
|
|||
RemoveUriParam("user");
|
||||
});
|
||||
|
||||
$(".status-filter-message").on("click", function()
|
||||
$(".status-filter-message").on("click", function ()
|
||||
{
|
||||
var value = $(this).data("status-filter");
|
||||
$("#status-filter").val(value);
|
||||
$("#status-filter").trigger("change");
|
||||
});
|
||||
|
||||
$(".user-filter-message").on("click", function()
|
||||
$(".user-filter-message").on("click", function ()
|
||||
{
|
||||
var value = $(this).data("user-filter");
|
||||
$("#user-filter").val(value);
|
||||
$("#user-filter").trigger("change");
|
||||
});
|
||||
|
||||
$(document).on('click', '.track-chore-button', function(e)
|
||||
$(document).on('click', '.track-chore-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||
var now = $(e.currentTarget).hasClass("now");
|
||||
|
||||
Grocy.Api.Get('chores/' + choreId,
|
||||
function(choreDetails)
|
||||
function (choreDetails)
|
||||
{
|
||||
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
if ((skipped || !now) && choreDetails.next_estimated_execution_time != null)
|
||||
|
|
@ -113,10 +113,10 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||
}
|
||||
|
||||
Grocy.Api.Post('chores/' + choreId + '/execute', { 'tracked_time': trackedTime, 'skipped': skipped },
|
||||
function()
|
||||
function ()
|
||||
{
|
||||
Grocy.Api.Get('chores/' + choreId,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var choreRow = $('#chore-' + choreId + '-row');
|
||||
var nextXDaysThreshold = moment().add($("#info-due-soon-chores").data("next-x-days"), "days");
|
||||
|
|
@ -177,7 +177,7 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||
RefreshStatistics();
|
||||
|
||||
// Delay due to delayed/animated set of new timestamps above
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
RefreshContextualTimeago("#chore-" + choreId + "-row");
|
||||
|
||||
|
|
@ -186,21 +186,21 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||
$(".input-group-filter").trigger("change");
|
||||
}, Grocy.FormFocusDelay);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("choretracking-form");
|
||||
console.error(xhr);
|
||||
|
|
@ -208,12 +208,12 @@ $(document).on('click', '.track-chore-button', function(e)
|
|||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.chore-grocycode-label-print', function(e)
|
||||
$(document).on('click', '.chore-grocycode-label-print', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var choreId = $(e.currentTarget).attr('data-chore-id');
|
||||
Grocy.Api.Get('chores/' + choreId + '/printlabel', function(labelData)
|
||||
Grocy.Api.Get('chores/' + choreId + '/printlabel', function (labelData)
|
||||
{
|
||||
if (Grocy.Webhooks.labelprinter !== undefined)
|
||||
{
|
||||
|
|
@ -226,7 +226,7 @@ function RefreshStatistics()
|
|||
{
|
||||
var nextXDays = $("#info-due-soon-chores").data("next-x-days");
|
||||
Grocy.Api.Get('chores',
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var dueTodayCount = 0;
|
||||
var dueSoonCount = 0;
|
||||
|
|
@ -265,20 +265,20 @@ function RefreshStatistics()
|
|||
$("#info-overdue-chores").html('<span class="d-block d-md-none">' + overdueCount + ' <i class="fa-solid fa-times-circle"></i></span><span class="d-none d-md-block">' + __n(overdueCount, '%s chore is overdue to be done', '%s chores are overdue to be done'));
|
||||
$("#info-assigned-to-me-chores").html('<span class="d-block d-md-none">' + assignedToMeCount + ' <i class="fa-solid fa-exclamation-circle"></i></span><span class="d-none d-md-block">' + __n(assignedToMeCount, '%s chore is assigned to me', '%s chores are assigned to me'));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).on("click", ".reschedule-chore-button", function(e)
|
||||
$(document).on("click", ".reschedule-chore-button", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var choreId = $(e.currentTarget).attr("data-chore-id");
|
||||
Grocy.EditObjectId = choreId;
|
||||
Grocy.Api.Get("chores/" + choreId, function(choreDetails)
|
||||
Grocy.Api.Get("chores/" + choreId, function (choreDetails)
|
||||
{
|
||||
var prefillDate = choreDetails.next_estimated_execution_time || moment().format("YYYY-MM-DD HH:mm:ss");
|
||||
if (choreDetails.chore.rescheduled_date)
|
||||
|
|
@ -316,7 +316,7 @@ $(document).on("click", ".reschedule-chore-button", function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#reschedule-chore-save-button").on("click", function(e)
|
||||
$("#reschedule-chore-save-button").on("click", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -326,45 +326,45 @@ $("#reschedule-chore-save-button").on("click", function(e)
|
|||
}
|
||||
|
||||
Grocy.Api.Put('objects/chores/' + Grocy.EditObjectId, { "rescheduled_date": Grocy.Components.DateTimePicker.GetValue(), "rescheduled_next_execution_assigned_to_user_id": Grocy.Components.UserPicker.GetValue() },
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
Grocy.Api.Post('chores/executions/calculate-next-assignments', { "chore_id": Grocy.EditObjectId },
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.reload();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$("#reschedule-chore-clear-button").on("click", function(e)
|
||||
$("#reschedule-chore-clear-button").on("click", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
Grocy.Api.Put('objects/chores/' + Grocy.EditObjectId, { "rescheduled_date": null, "rescheduled_next_execution_assigned_to_user_id": null },
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
Grocy.Api.Post('chores/executions/calculate-next-assignments', { "chore_id": Grocy.EditObjectId },
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.reload();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
$('#save-consume-button').on('click', function(e)
|
||||
$('#save-consume-button').on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -40,10 +40,10 @@
|
|||
|
||||
var bookingResponse = null;
|
||||
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
|
||||
function(productDetails)
|
||||
function (productDetails)
|
||||
{
|
||||
Grocy.Api.Post(apiUrl, jsonData,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
if (BoolVal(Grocy.UserSettings.scan_mode_consume_enabled))
|
||||
{
|
||||
|
|
@ -59,14 +59,14 @@
|
|||
jsonDataBarcode.product_id = jsonForm.product_id;
|
||||
|
||||
Grocy.Api.Post('objects/product_barcodes', jsonDataBarcode,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
$("#flow-info-InplaceAddBarcodeToExistingProduct").addClass("d-none");
|
||||
$('#barcode-lookup-disabled-hint').addClass('d-none');
|
||||
$('#barcode-lookup-hint').removeClass('d-none');
|
||||
window.history.replaceState({}, document.title, U("/consume"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
$("#consume-exact-amount-group").addClass("d-none");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
console.error(xhr);
|
||||
|
|
@ -146,7 +146,7 @@
|
|||
);
|
||||
});
|
||||
|
||||
$('#save-mark-as-open-button').on('click', function(e)
|
||||
$('#save-mark-as-open-button').on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -168,6 +168,7 @@ $('#save-mark-as-open-button').on('click', function(e)
|
|||
jsonData = {};
|
||||
jsonData.amount = jsonForm.amount;
|
||||
jsonData.allow_subproduct_substitution = true;
|
||||
jsonData.location_id = jsonForm.location_id;
|
||||
|
||||
if ($("#use_specific_stock_entry").is(":checked"))
|
||||
{
|
||||
|
|
@ -175,10 +176,10 @@ $('#save-mark-as-open-button').on('click', function(e)
|
|||
}
|
||||
|
||||
Grocy.Api.Get('stock/products/' + jsonForm.product_id,
|
||||
function(productDetails)
|
||||
function (productDetails)
|
||||
{
|
||||
Grocy.Api.Post(apiUrl, jsonData,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
$("#specific_stock_entry").find("option").remove().end().append("<option></option>");
|
||||
if ($("#use_specific_stock_entry").is(":checked"))
|
||||
|
|
@ -206,16 +207,17 @@ $('#save-mark-as-open-button').on('click', function(e)
|
|||
$(".input-group-productamountpicker").trigger("change");
|
||||
Grocy.Components.ProductPicker.Clear();
|
||||
Grocy.Components.ProductPicker.GetInputElement().focus();
|
||||
Grocy.Components.ProductCard.Refresh(jsonForm.product_id);
|
||||
Grocy.FrontendHelpers.ValidateForm('consume-form');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy("consume-form");
|
||||
console.error(xhr);
|
||||
|
|
@ -223,7 +225,8 @@ $('#save-mark-as-open-button').on('click', function(e)
|
|||
);
|
||||
});
|
||||
var sumValue = 0;
|
||||
$("#location_id").on('change', function(e)
|
||||
var sumValueOpened = 0;
|
||||
$("#location_id").on('change', function (e)
|
||||
{
|
||||
var locationId = $(e.target).val();
|
||||
$("#specific_stock_entry").find("option").remove().end().append("<option></option>");
|
||||
|
|
@ -245,12 +248,12 @@ $("#location_id").on('change', function(e)
|
|||
if (gc.length == 4)
|
||||
{
|
||||
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries?query[]=stock_id=' + gc[3],
|
||||
function(stockEntries)
|
||||
function (stockEntries)
|
||||
{
|
||||
OnLocationChange(stockEntries[0].location_id, gc[3]);
|
||||
$('#display_amount').val(stockEntries[0].amount);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -271,6 +274,7 @@ $("#location_id").on('change', function(e)
|
|||
function OnLocationChange(locationId, stockId)
|
||||
{
|
||||
sumValue = 0;
|
||||
sumValueOpened = 0;
|
||||
|
||||
if (locationId)
|
||||
{
|
||||
|
|
@ -280,7 +284,7 @@ function OnLocationChange(locationId, stockId)
|
|||
}
|
||||
|
||||
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries?include_sub_products=true',
|
||||
function(stockEntries)
|
||||
function (stockEntries)
|
||||
{
|
||||
stockEntries.forEach(stockEntry =>
|
||||
{
|
||||
|
|
@ -307,6 +311,11 @@ function OnLocationChange(locationId, stockId)
|
|||
|
||||
sumValue = sumValue + (stockEntry.amount || 0);
|
||||
|
||||
if (BoolVal(stockEntry.open))
|
||||
{
|
||||
sumValueOpened = sumValueOpened + (stockEntry.amount || 0);
|
||||
}
|
||||
|
||||
if (stockEntry.stock_id == stockId)
|
||||
{
|
||||
$("#use_specific_stock_entry").click();
|
||||
|
|
@ -315,13 +324,15 @@ function OnLocationChange(locationId, stockId)
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
Grocy.Api.Get('stock/products/' + Grocy.Components.ProductPicker.GetValue(),
|
||||
function(productDetails)
|
||||
function (productDetails)
|
||||
{
|
||||
current_productDetails = productDetails;
|
||||
RefreshForm();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -332,7 +343,7 @@ function OnLocationChange(locationId, stockId)
|
|||
ScanModeSubmit();
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -340,7 +351,7 @@ function OnLocationChange(locationId, stockId)
|
|||
}
|
||||
}
|
||||
|
||||
Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
||||
Grocy.Components.ProductPicker.GetPicker().on('change', function (e)
|
||||
{
|
||||
if (BoolVal(Grocy.UserSettings.scan_mode_consume_enabled))
|
||||
{
|
||||
|
|
@ -361,7 +372,7 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
Grocy.Components.ProductCard.Refresh(productId);
|
||||
|
||||
Grocy.Api.Get('stock/products/' + productId,
|
||||
function(productDetails)
|
||||
function (productDetails)
|
||||
{
|
||||
current_productDetails = productDetails;
|
||||
|
||||
|
|
@ -386,7 +397,7 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
|
||||
$("#location_id").find("option").remove().end().append("<option></option>");
|
||||
Grocy.Api.Get("stock/products/" + productId + '/locations?include_sub_products=true',
|
||||
function(stockLocations)
|
||||
function (stockLocations)
|
||||
{
|
||||
var setDefault = 0;
|
||||
var stockAmountAtDefaultLocation = 0;
|
||||
|
|
@ -436,7 +447,7 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
if (document.getElementById("product_id").getAttribute("barcode") != "null")
|
||||
{
|
||||
Grocy.Api.Get('objects/product_barcodes?query[]=barcode=' + document.getElementById("product_id").getAttribute("barcode"),
|
||||
function(barcodeResult)
|
||||
function (barcodeResult)
|
||||
{
|
||||
if (barcodeResult != null)
|
||||
{
|
||||
|
|
@ -462,14 +473,14 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
}
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -489,21 +500,12 @@ Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
|||
|
||||
Grocy.Components.ProductPicker.HideCustomError();
|
||||
Grocy.FrontendHelpers.ValidateForm('consume-form');
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$('#display_amount').focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
||||
if (productDetails.stock_amount == productDetails.stock_amount_opened || productDetails.product.enable_tare_weight_handling == 1 || productDetails.product.disable_open == 1)
|
||||
{
|
||||
$("#save-mark-as-open-button").addClass("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#save-mark-as-open-button").removeClass("disabled");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -515,28 +517,44 @@ $('#display_amount').val(Grocy.UserSettings.stock_default_consume_amount);
|
|||
$(".input-group-productamountpicker").trigger("change");
|
||||
Grocy.FrontendHelpers.ValidateForm('consume-form');
|
||||
|
||||
$('#display_amount').on('focus', function(e)
|
||||
$('#display_amount').on('focus', function (e)
|
||||
{
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
$('#price').on('focus', function(e)
|
||||
$('#price').on('focus', function (e)
|
||||
{
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
|
||||
$('#consume-form input').keyup(function(event)
|
||||
$('#consume-form input').keyup(function (event)
|
||||
{
|
||||
Grocy.FrontendHelpers.ValidateForm('consume-form');
|
||||
});
|
||||
|
||||
$('#consume-form select').change(function(event)
|
||||
$('#consume-form select').change(function (event)
|
||||
{
|
||||
Grocy.FrontendHelpers.ValidateForm('consume-form');
|
||||
});
|
||||
|
||||
$('#consume-form input').keydown(function(event)
|
||||
$("#display_amount").on("keyup", function (e)
|
||||
{
|
||||
if (!current_productDetails)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ($("#display_amount").val() > sumValue - sumValueOpened || current_productDetails.product.enable_tare_weight_handling == 1 || current_productDetails.product.disable_open == 1)
|
||||
{
|
||||
$("#save-mark-as-open-button").addClass("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#save-mark-as-open-button").removeClass("disabled");
|
||||
}
|
||||
});
|
||||
|
||||
$('#consume-form input').keydown(function (event)
|
||||
{
|
||||
if (event.keyCode === 13) // Enter
|
||||
{
|
||||
|
|
@ -553,28 +571,45 @@ $('#consume-form input').keydown(function(event)
|
|||
}
|
||||
});
|
||||
|
||||
$("#specific_stock_entry").on("change", function(e)
|
||||
$("#specific_stock_entry").on("change", function (e)
|
||||
{
|
||||
if ($(e.target).val() == "")
|
||||
{
|
||||
sumValue = 0;
|
||||
sumValueOpened = 0;
|
||||
Grocy.Api.Get("stock/products/" + Grocy.Components.ProductPicker.GetValue() + '/entries?include_sub_products=true',
|
||||
function(stockEntries)
|
||||
function (stockEntries)
|
||||
{
|
||||
stockEntries.forEach(stockEntry =>
|
||||
{
|
||||
if (stockEntry.location_id == $("#location_id").val() || stockEntry.location_id == "")
|
||||
{
|
||||
sumValue = sumValue + stockEntry.amount_aggregated;
|
||||
sumValue = sumValue + (stockEntry.amount || 0);
|
||||
|
||||
if (BoolVal(stockEntry.open))
|
||||
{
|
||||
sumValueOpened = sumValueOpened + (stockEntry.amount || 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$("#display_amount").attr("max", sumValue.toFixed(Grocy.UserSettings.stock_decimal_places_amounts));
|
||||
|
||||
if (sumValue == 0)
|
||||
{
|
||||
$("#display_amount").parent().find(".invalid-feedback").text(__t('There are no units available at this location'));
|
||||
}
|
||||
|
||||
if (sumValue == sumValueOpened || current_productDetails.product.enable_tare_weight_handling == 1 || current_productDetails.product.disable_open == 1)
|
||||
{
|
||||
$("#save-mark-as-open-button").addClass("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#save-mark-as-open-button").removeClass("disabled");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -586,7 +621,7 @@ $("#specific_stock_entry").on("change", function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$("#use_specific_stock_entry").on("change", function()
|
||||
$("#use_specific_stock_entry").on("change", function ()
|
||||
{
|
||||
var value = $(this).is(":checked");
|
||||
|
||||
|
|
@ -605,7 +640,7 @@ $("#use_specific_stock_entry").on("change", function()
|
|||
Grocy.FrontendHelpers.ValidateForm("consume-form");
|
||||
});
|
||||
|
||||
$("#qu_id").on("change", function()
|
||||
$("#qu_id").on("change", function ()
|
||||
{
|
||||
RefreshForm();
|
||||
});
|
||||
|
|
@ -613,11 +648,11 @@ $("#qu_id").on("change", function()
|
|||
function UndoStockBooking(bookingId)
|
||||
{
|
||||
Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
toastr.success(__t("Booking successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -627,11 +662,11 @@ function UndoStockBooking(bookingId)
|
|||
function UndoStockTransaction(transactionId)
|
||||
{
|
||||
Grocy.Api.Post('stock/transactions/' + transactionId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
toastr.success(__t("Transaction successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -657,12 +692,12 @@ if (GetUriParam("embedded") !== undefined)
|
|||
}
|
||||
|
||||
// Default input field
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
||||
$(document).on("change", "#scan-mode", function(e)
|
||||
$(document).on("change", "#scan-mode", function (e)
|
||||
{
|
||||
if ($(this).prop("checked"))
|
||||
{
|
||||
|
|
@ -670,7 +705,7 @@ $(document).on("change", "#scan-mode", function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$("#scan-mode-button").on("click", function(e)
|
||||
$("#scan-mode-button").on("click", function (e)
|
||||
{
|
||||
$("#scan-mode").click();
|
||||
$("#scan-mode-button").toggleClass("btn-success").toggleClass("btn-danger");
|
||||
|
|
@ -727,6 +762,15 @@ function RefreshForm()
|
|||
$("#display_amount").removeAttr("max");
|
||||
}
|
||||
|
||||
if (sumValue == sumValueOpened || productDetails.product.enable_tare_weight_handling == 1 || productDetails.product.disable_open == 1)
|
||||
{
|
||||
$("#save-mark-as-open-button").addClass("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#save-mark-as-open-button").removeClass("disabled");
|
||||
}
|
||||
|
||||
Grocy.FrontendHelpers.ValidateForm("consume-form");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
equipmentTable.search(value).draw();
|
||||
equipmentTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#locations-table tbody').removeClass("d-none");
|
||||
locationsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
locationsTable.search(value).draw();
|
||||
locationsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
locationsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.location-delete-button', function(e)
|
||||
$(document).on('click', '.location-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-location-name');
|
||||
var objectId = $(e.currentTarget).attr('data-location-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.location-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/locations/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/locations');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ $(document).on('click', '.location-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ $("#login-button").on("click", function (e)
|
|||
{
|
||||
e.preventDefault();
|
||||
|
||||
$("#password_base64").val(btoa($("#password_input").val()));
|
||||
$("#password_base64").val(btoa(String.fromCharCode(...new TextEncoder().encode($("#password_input").val()))));
|
||||
$("#login-form").trigger("submit");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#apikeys-table tbody').removeClass("d-none");
|
||||
apiKeysTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
apiKeysTable.search(value).draw();
|
||||
apiKeysTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
apiKeysTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.apikey-delete-button', function(e)
|
||||
$(document).on('click', '.apikey-delete-button', function (e)
|
||||
{
|
||||
var button = $(e.currentTarget);
|
||||
var objectName = button.attr('data-apikey-key');
|
||||
|
|
@ -51,16 +51,16 @@ $(document).on('click', '.apikey-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/api_keys/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/manageapikeys');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ $(document).on('click', '.apikey-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$(".apikey-show-qr-button").on("click", function()
|
||||
$(".apikey-show-qr-button").on("click", function ()
|
||||
{
|
||||
var button = $(this);
|
||||
var apiKey = button.data("apikey-key");
|
||||
|
|
@ -89,20 +89,20 @@ $(".apikey-show-qr-button").on("click", function()
|
|||
});
|
||||
});
|
||||
|
||||
$("#add-api-key-button").on("click", function(e)
|
||||
$("#add-api-key-button").on("click", function (e)
|
||||
{
|
||||
$("#add-api-key-modal").modal("show");
|
||||
});
|
||||
|
||||
$("#add-api-key-modal").on("shown.bs.modal", function(e)
|
||||
$("#add-api-key-modal").on("shown.bs.modal", function (e)
|
||||
{
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$("#description").focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
});
|
||||
|
||||
$("#new-api-key-button").on("click", function(e)
|
||||
$("#new-api-key-button").on("click", function (e)
|
||||
{
|
||||
window.location.href = U("/manageapikeys/new?description=" + encodeURIComponent($("#description").val()));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
sessionsTable.search(value).draw();
|
||||
sessionsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#mealplansections-table tbody').removeClass("d-none");
|
||||
mealplanSectionsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
mealplanSectionsTable.search(value).draw();
|
||||
mealplanSectionsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
mealplanSectionsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.mealplansection-delete-button', function(e)
|
||||
$(document).on('click', '.mealplansection-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-mealplansection-name');
|
||||
var objectId = $(e.currentTarget).attr('data-mealplansection-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.mealplansection-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/meal_plan_sections/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/mealplansections');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,86 +392,7 @@ $(window).on("message", function (e)
|
|||
}
|
||||
});
|
||||
|
||||
if (Grocy.EditMode == "create" && GetUriParam("copy-of") != undefined)
|
||||
{
|
||||
Grocy.Api.Get('objects/products/' + GetUriParam("copy-of"),
|
||||
function (sourceProduct)
|
||||
{
|
||||
if (sourceProduct.parent_product_id != null)
|
||||
{
|
||||
Grocy.Components.ProductPicker.SetId(sourceProduct.parent_product_id);
|
||||
}
|
||||
if (sourceProduct.description)
|
||||
{
|
||||
$("#description").summernote("pasteHTML", sourceProduct.description);
|
||||
}
|
||||
$("#location_id").val(sourceProduct.location_id);
|
||||
if (sourceProduct.shopping_location_id != null)
|
||||
{
|
||||
Grocy.Components.ShoppingLocationPicker.SetId(sourceProduct.shopping_location_id);
|
||||
}
|
||||
$("#min_stock_amount").val(sourceProduct.min_stock_amount);
|
||||
if (BoolVal(sourceProduct.cumulate_min_stock_amount_of_sub_products))
|
||||
{
|
||||
$("#cumulate_min_stock_amount_of_sub_products").prop("checked", true);
|
||||
}
|
||||
$("#default_best_before_days").val(sourceProduct.default_best_before_days);
|
||||
$("#default_best_before_days_after_open").val(sourceProduct.default_best_before_days_after_open);
|
||||
if (sourceProduct.product_group_id != null)
|
||||
{
|
||||
$("#product_group_id").val(sourceProduct.product_group_id);
|
||||
}
|
||||
$("#qu_id_stock").val(sourceProduct.qu_id_stock);
|
||||
$("#qu_id_purchase").val(sourceProduct.qu_id_purchase);
|
||||
if (BoolVal(sourceProduct.enable_tare_weight_handling))
|
||||
{
|
||||
$("#enable_tare_weight_handling").prop("checked", true);
|
||||
}
|
||||
$("#tare_weight").val(sourceProduct.tare_weight);
|
||||
if (BoolVal(sourceProduct.not_check_stock_fulfillment_for_recipes))
|
||||
{
|
||||
$("#not_check_stock_fulfillment_for_recipes").prop("checked", true);
|
||||
}
|
||||
if (sourceProduct.calories != null)
|
||||
{
|
||||
$("#calories").val(sourceProduct.calories);
|
||||
}
|
||||
$("#default_best_before_days_after_freezing").val(sourceProduct.default_best_before_days_after_freezing);
|
||||
$("#default_best_before_days_after_thawing").val(sourceProduct.default_best_before_days_after_thawing);
|
||||
$("#quick_consume_amount").val(sourceProduct.quick_consume_amount);
|
||||
$("#quick_open_amount").val(sourceProduct.quick_open_amount);
|
||||
$("#default_consume_location_id").val(sourceProduct.default_consume_location_id);
|
||||
if (BoolVal(sourceProduct.no_own_stock))
|
||||
{
|
||||
$("#no_own_stock").prop("checked", true);
|
||||
}
|
||||
if (BoolVal(sourceProduct.hide_on_stock_overview))
|
||||
{
|
||||
$("#hide_on_stock_overview").prop("checked", true);
|
||||
}
|
||||
if (BoolVal(sourceProduct.auto_reprint_stock_label))
|
||||
{
|
||||
$("#auto_reprint_stock_label").prop("checked", true);
|
||||
}
|
||||
$("#default_stock_label_type").val(sourceProduct.default_stock_label_type);
|
||||
if (BoolVal(sourceProduct.move_on_open))
|
||||
{
|
||||
$("#move_on_open").prop("checked", true);
|
||||
}
|
||||
if (BoolVal(sourceProduct.treat_opened_as_out_of_stock))
|
||||
{
|
||||
$("#treat_opened_as_out_of_stock").prop("checked", true);
|
||||
}
|
||||
|
||||
Grocy.FrontendHelpers.ValidateForm('product-form');
|
||||
},
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (Grocy.EditMode === 'create')
|
||||
if (Grocy.EditMode === 'create')
|
||||
{
|
||||
if (Grocy.UserSettings.product_presets_location_id.toString() !== '-1')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#productgroups-table tbody').removeClass("d-none");
|
||||
groupsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
groupsTable.search(value).draw();
|
||||
groupsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
groupsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.product-group-delete-button', function(e)
|
||||
$(document).on('click', '.product-group-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-group-name');
|
||||
var objectId = $(e.currentTarget).attr('data-group-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.product-group-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/product_groups/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/productgroups');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ $(document).on('click', '.product-group-delete-button', function(e)
|
|||
}
|
||||
});
|
||||
});
|
||||
$(window).on("message", function(e)
|
||||
$(window).on("message", function (e)
|
||||
{
|
||||
var data = e.originalEvent.data;
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ $(window).on("message", function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
productsTable.search(value).draw();
|
||||
productsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#product-group-filter").on("change", function ()
|
||||
|
|
@ -32,7 +32,7 @@ $("#product-group-filter").on("change", function ()
|
|||
}
|
||||
else
|
||||
{
|
||||
productsTable.column(productsTable.colReorder.transpose(6)).search("^" + $.fn.dataTable.util.escapeRegex(value) + "$", true, false).draw();
|
||||
productsTable.column(productsTable.colReorder.transpose(6)).search("^" + $.fn.dataTable.util.escapeRegex(value.accentNeutralise()) + "$", true, false).draw();
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -175,3 +175,21 @@ $("#merge-products-save-button").on("click", function (e)
|
|||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(".product-copy-button").on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var objectId = $(e.currentTarget).attr("data-product-id");
|
||||
|
||||
Grocy.Api.Post("stock/products/" + objectId.toString() + "/copy", {},
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U("/product/" + result.created_object_id.toString());
|
||||
},
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#qu-conversions-resolved-table tbody').removeClass("d-none");
|
||||
quConversionsResolvedTable.columns.adjust().draw();
|
||||
|
||||
$("#quantity-unit-filter").on("change", function()
|
||||
$("#quantity-unit-filter").on("change", function ()
|
||||
{
|
||||
var value = $("#quantity-unit-filter option:selected").text();
|
||||
if (value === __t("All"))
|
||||
|
|
@ -16,10 +16,10 @@ $("#quantity-unit-filter").on("change", function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
quConversionsResolvedTable.column([quConversionsResolvedTable.colReorder.transpose(1), quConversionsResolvedTable.colReorder.transpose(2)]).search(value).draw();
|
||||
quConversionsResolvedTable.column([quConversionsResolvedTable.colReorder.transpose(1), quConversionsResolvedTable.colReorder.transpose(2)]).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#quantity-unit-filter").val("all");
|
||||
quConversionsResolvedTable.column([quConversionsResolvedTable.colReorder.transpose(1), quConversionsResolvedTable.colReorder.transpose(2)]).search("").draw();
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#quantityunits-table tbody').removeClass("d-none");
|
||||
quantityUnitsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
quantityUnitsTable.search(value).draw();
|
||||
quantityUnitsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
quantityUnitsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.quantityunit-delete-button', function(e)
|
||||
$(document).on('click', '.quantityunit-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-quantityunit-name');
|
||||
var objectId = $(e.currentTarget).attr('data-quantityunit-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.quantityunit-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/quantity_units/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/quantityunits');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ $(document).on('click', '.quantityunit-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
style: 'single',
|
||||
selector: 'tr td:not(:first-child)'
|
||||
},
|
||||
'initComplete': function()
|
||||
'initComplete': function ()
|
||||
{
|
||||
this.api().row({ order: 'current' }, 0).select();
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ if (typeof recipe !== "undefined")
|
|||
if (GetUriParam("search") !== undefined)
|
||||
{
|
||||
$("#search").val(GetUriParam("search"));
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$("#search").keyup();
|
||||
}, 50);
|
||||
|
|
@ -53,23 +53,23 @@ if (GetUriParam("search") !== undefined)
|
|||
if (GetUriParam("status") !== undefined)
|
||||
{
|
||||
$("#status-filter").val(GetUriParam("status"));
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$("#status-filter").trigger("change");
|
||||
}, 50);
|
||||
}
|
||||
|
||||
$("a[data-toggle='tab']").on("shown.bs.tab", function(e)
|
||||
$("a[data-toggle='tab']").on("shown.bs.tab", function (e)
|
||||
{
|
||||
var tabId = $(e.target).attr("id");
|
||||
window.localStorage.setItem("recipes_last_tab_id", tabId);
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
|
||||
recipesTables.search(value).draw();
|
||||
recipesTables.search(value.accentNeutralise()).draw();
|
||||
|
||||
if (!value)
|
||||
{
|
||||
|
|
@ -84,7 +84,7 @@ $("#search").on("keyup", Delay(function()
|
|||
$(".recipe-gallery-item .card-title-search:not(:contains_case_insensitive(" + value + "))").parent().parent().parent().addClass("d-none");
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#status-filter").val("all");
|
||||
|
|
@ -92,7 +92,7 @@ $("#clear-filter-button").on("click", function()
|
|||
$("#status-filter").trigger("change");
|
||||
});
|
||||
|
||||
$("#status-filter").on("change", function()
|
||||
$("#status-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -100,7 +100,7 @@ $("#status-filter").on("change", function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
recipesTables.column(recipesTables.colReorder.transpose(6)).search(value).draw();
|
||||
recipesTables.column(recipesTables.colReorder.transpose(6)).search(value.accentNeutralise()).draw();
|
||||
|
||||
$('.recipe-gallery-item').removeClass('d-none');
|
||||
if (value !== "")
|
||||
|
|
@ -129,7 +129,7 @@ $("#status-filter").on("change", function()
|
|||
}
|
||||
});
|
||||
|
||||
$(".recipe-delete").on('click', function(e)
|
||||
$(".recipe-delete").on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -149,16 +149,16 @@ $(".recipe-delete").on('click', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/recipes/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/recipes');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -168,25 +168,25 @@ $(".recipe-delete").on('click', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$(".recipe-copy").on('click', function(e)
|
||||
$(".recipe-copy").on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var objectId = $(e.currentTarget).attr('data-recipe-id');
|
||||
|
||||
Grocy.Api.Post("recipes/" + objectId.toString() + "/copy", {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/recipes?recipe=' + result.created_object_id.toString());
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.recipe-shopping-list', function(e)
|
||||
$(document).on('click', '.recipe-shopping-list', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-recipe-name');
|
||||
var objectId = $(e.currentTarget).attr('data-recipe-id');
|
||||
|
|
@ -204,24 +204,24 @@ $(document).on('click', '.recipe-shopping-list', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.FrontendHelpers.BeginUiBusy();
|
||||
|
||||
var excludedProductIds = new Array();
|
||||
$(".missing-recipe-pos-product-checkbox:checkbox:not(:checked)").each(function()
|
||||
$(".missing-recipe-pos-product-checkbox:checkbox:not(:checked)").each(function ()
|
||||
{
|
||||
excludedProductIds.push($(this).data("product-id"));
|
||||
});
|
||||
|
||||
Grocy.Api.Post('recipes/' + objectId + '/add-not-fulfilled-products-to-shoppinglist', { "excludedProductIds": excludedProductIds },
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.reload();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
|
|
@ -232,7 +232,7 @@ $(document).on('click', '.recipe-shopping-list', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$(".recipe-consume").on('click', function(e)
|
||||
$(".recipe-consume").on('click', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-recipe-name');
|
||||
var objectId = $(e.currentTarget).attr('data-recipe-id');
|
||||
|
|
@ -251,19 +251,19 @@ $(".recipe-consume").on('click', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.FrontendHelpers.BeginUiBusy();
|
||||
|
||||
Grocy.Api.Post('recipes/' + objectId + '/consume', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
toastr.success(__t('Removed all in stock ingredients needed by recipe \"%s\" from stock', objectName));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
Grocy.FrontendHelpers.ShowGenericError("A server error occured while processing your request", xhr.response);
|
||||
|
|
@ -274,7 +274,7 @@ $(".recipe-consume").on('click', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
recipesTables.on('select', function(e, dt, type, indexes)
|
||||
recipesTables.on('select', function (e, dt, type, indexes)
|
||||
{
|
||||
if (type === 'row')
|
||||
{
|
||||
|
|
@ -302,7 +302,7 @@ recipesTables.on('select', function(e, dt, type, indexes)
|
|||
cancel: {
|
||||
label: __t('Close'),
|
||||
className: 'btn-secondary responsive-button',
|
||||
callback: function()
|
||||
callback: function ()
|
||||
{
|
||||
$(".modal").last().modal("hide");
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ recipesTables.on('select', function(e, dt, type, indexes)
|
|||
}
|
||||
});
|
||||
|
||||
$(".recipe-gallery-item").on("click", function(e)
|
||||
$(".recipe-gallery-item").on("click", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ $(".recipe-gallery-item").on("click", function(e)
|
|||
cancel: {
|
||||
label: __t('Close'),
|
||||
className: 'btn-secondary responsive-button',
|
||||
callback: function()
|
||||
callback: function ()
|
||||
{
|
||||
$(".modal").last().modal("hide");
|
||||
}
|
||||
|
|
@ -346,12 +346,12 @@ $(".recipe-gallery-item").on("click", function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$(".recipe-edit-button").on("click", function(e)
|
||||
$(".recipe-edit-button").on("click", function (e)
|
||||
{
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
$(".recipe-fullscreen").on('click', function(e)
|
||||
$(".recipe-fullscreen").on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -374,7 +374,7 @@ $(".recipe-fullscreen").on('click', function(e)
|
|||
}
|
||||
});
|
||||
|
||||
$(".recipe-print").on('click', function(e)
|
||||
$(".recipe-print").on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -387,24 +387,24 @@ $(".recipe-print").on('click', function(e)
|
|||
window.print();
|
||||
});
|
||||
|
||||
$('#servings-scale').keyup(function(event)
|
||||
$('#servings-scale').keyup(function (event)
|
||||
{
|
||||
var data = {};
|
||||
data.desired_servings = $(this).val();
|
||||
|
||||
Grocy.Api.Put('objects/recipes/' + $(this).data("recipe-id"), data,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.reload();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$(document).on("click", ".missing-recipe-pos-select-button", function(e)
|
||||
$(document).on("click", ".missing-recipe-pos-select-button", function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ $(document).on("click", ".missing-recipe-pos-select-button", function(e)
|
|||
$(this).toggleClass("list-group-item-primary");
|
||||
});
|
||||
|
||||
$(document).on("click", ".missing-recipe-pos-product-checkbox", function(e)
|
||||
$(document).on("click", ".missing-recipe-pos-product-checkbox", function (e)
|
||||
{
|
||||
e.stopPropagation();
|
||||
|
||||
|
|
@ -427,12 +427,12 @@ if (window.location.hash === "#fullscreen")
|
|||
$("#selectedRecipeToggleFullscreenButton").click();
|
||||
}
|
||||
|
||||
$(document).on('click', '.recipe-grocycode-label-print', function(e)
|
||||
$(document).on('click', '.recipe-grocycode-label-print', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var recipeId = $(e.currentTarget).attr('data-recipe-id');
|
||||
Grocy.Api.Get('recipes/' + recipeId + '/printlabel', function(labelData)
|
||||
Grocy.Api.Get('recipes/' + recipeId + '/printlabel', function (labelData)
|
||||
{
|
||||
if (Grocy.Webhooks.labelprinter !== undefined)
|
||||
{
|
||||
|
|
@ -441,14 +441,14 @@ $(document).on('click', '.recipe-grocycode-label-print', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.ingredient-done-button', function(e)
|
||||
$(document).on('click', '.ingredient-done-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
$(e.currentTarget).parent().toggleClass("text-strike-through").toggleClass("text-muted");
|
||||
});
|
||||
|
||||
$(document).on("click", ".add-to-mealplan-button", function(e)
|
||||
$(document).on("click", ".add-to-mealplan-button", function (e)
|
||||
{
|
||||
Grocy.Components.DateTimePicker.Init(true);
|
||||
Grocy.Components.DateTimePicker.SetValue(moment().format("YYYY-MM-DD"));
|
||||
|
|
@ -461,7 +461,7 @@ $(document).on("click", ".add-to-mealplan-button", function(e)
|
|||
$("#recipe_servings").focus();
|
||||
});
|
||||
|
||||
$('#save-add-to-mealplan-button').on('click', function(e)
|
||||
$('#save-add-to-mealplan-button').on('click', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -474,19 +474,19 @@ $('#save-add-to-mealplan-button').on('click', function(e)
|
|||
formData.day = Grocy.Components.DateTimePicker.GetValue();
|
||||
|
||||
Grocy.Api.Post('objects/meal_plan', formData,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
toastr.success(__t("Successfully added the recipe to the meal plan"));
|
||||
$("#add-to-mealplan-modal").modal("hide");
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('#add-to-mealplan-form input').keydown(function(event)
|
||||
$('#add-to-mealplan-form input').keydown(function (event)
|
||||
{
|
||||
if (event.keyCode === 13) // Enter
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
shoppingListTable.search(value).draw();
|
||||
shoppingListTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
|
|
@ -65,7 +65,7 @@ $("#status-filter").on("change", function ()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
shoppingListTable.column(shoppingListTable.colReorder.transpose(4)).search(value).draw();
|
||||
shoppingListTable.column(shoppingListTable.colReorder.transpose(4)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#selected-shopping-list").on("change", function ()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ var locationsTable = $('#shoppinglocations-table').DataTable({
|
|||
$('#shoppinglocations-table tbody').removeClass("d-none");
|
||||
locationsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
locationsTable.search(value).draw();
|
||||
locationsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
locationsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.shoppinglocation-delete-button', function(e)
|
||||
$(document).on('click', '.shoppinglocation-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-shoppinglocation-name');
|
||||
var objectId = $(e.currentTarget).attr('data-shoppinglocation-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.shoppinglocation-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/shopping_locations/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/shoppinglocations');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ $(document).on('click', '.shoppinglocation-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
$('#stockentries-table tbody').removeClass("d-none");
|
||||
stockEntriesTable.columns.adjust().draw();
|
||||
|
||||
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex)
|
||||
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex)
|
||||
{
|
||||
var productId = Grocy.Components.ProductPicker.GetValue();
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ $.fn.dataTable.ext.search.push(function(settings, data, dataIndex)
|
|||
return false;
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#location-filter").val("all");
|
||||
$("#location-filter").trigger("change");
|
||||
|
|
@ -40,7 +40,7 @@ $("#clear-filter-button").on("click", function()
|
|||
stockEntriesTable.draw();
|
||||
});
|
||||
|
||||
$("#location-filter").on("change", function()
|
||||
$("#location-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#location-filter option:selected").text();
|
||||
|
|
@ -49,20 +49,20 @@ $("#location-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
stockEntriesTable.column(stockEntriesTable.colReorder.transpose(5)).search(text).draw();
|
||||
stockEntriesTable.column(stockEntriesTable.colReorder.transpose(5)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
Grocy.Components.ProductPicker.GetPicker().on('change', function(e)
|
||||
Grocy.Components.ProductPicker.GetPicker().on('change', function (e)
|
||||
{
|
||||
stockEntriesTable.draw();
|
||||
});
|
||||
|
||||
Grocy.Components.ProductPicker.GetInputElement().on('keyup', function(e)
|
||||
Grocy.Components.ProductPicker.GetInputElement().on('keyup', function (e)
|
||||
{
|
||||
stockEntriesTable.draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.stock-consume-button', function(e)
|
||||
$(document).on('click', '.stock-consume-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -77,10 +77,10 @@ $(document).on('click', '.stock-consume-button', function(e)
|
|||
var wasSpoiled = $(e.currentTarget).hasClass("stock-consume-button-spoiled");
|
||||
|
||||
Grocy.Api.Post('stock/products/' + productId + '/consume', { 'amount': consumeAmount, 'spoiled': wasSpoiled, 'location_id': locationId, 'stock_entry_id': specificStockEntryId, 'exact_amount': true },
|
||||
function(bookingResponse)
|
||||
function (bookingResponse)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + productId,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var toastMessage = __t('Removed %1$s of %2$s from stock', consumeAmount.toLocaleString({ minimumFractionDigits: 0, maximumFractionDigits: Grocy.UserSettings.stock_decimal_places_amounts }) + " " + __n(consumeAmount, result.quantity_unit_stock.name, result.quantity_unit_stock.name_plural, true), result.product.name);
|
||||
if (wasSpoiled)
|
||||
|
|
@ -94,14 +94,14 @@ $(document).on('click', '.stock-consume-button', function(e)
|
|||
toastr.success(toastMessage);
|
||||
Grocy.GetTopmostWindow().postMessage(WindowMessageBag("BroadcastMessage", WindowMessageBag("ProductChanged", productId)), Grocy.BaseUrl);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
|
|
@ -109,7 +109,7 @@ $(document).on('click', '.stock-consume-button', function(e)
|
|||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.product-open-button', function(e)
|
||||
$(document).on('click', '.product-open-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -122,10 +122,10 @@ $(document).on('click', '.product-open-button', function(e)
|
|||
var button = $(e.currentTarget);
|
||||
|
||||
Grocy.Api.Post('stock/products/' + productId + '/open', { 'amount': openAmount, 'stock_entry_id': specificStockEntryId },
|
||||
function(bookingResponse)
|
||||
function (bookingResponse)
|
||||
{
|
||||
Grocy.Api.Get('stock/products/' + productId,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
button.addClass("disabled");
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
|
|
@ -139,14 +139,14 @@ $(document).on('click', '.product-open-button', function(e)
|
|||
RefreshStockEntryRow(stockRowId);
|
||||
Grocy.GetTopmostWindow().postMessage(WindowMessageBag("BroadcastMessage", WindowMessageBag("ProductChanged", productId)), Grocy.BaseUrl);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
|
|
@ -154,12 +154,12 @@ $(document).on('click', '.product-open-button', function(e)
|
|||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.stockentry-grocycode-label-print', function(e)
|
||||
$(document).on('click', '.stockentry-grocycode-label-print', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var stockId = $(e.currentTarget).attr('data-stock-id');
|
||||
Grocy.Api.Get('stock/entry/' + stockId + '/printlabel', function(labelData)
|
||||
Grocy.Api.Get('stock/entry/' + stockId + '/printlabel', function (labelData)
|
||||
{
|
||||
if (Grocy.Webhooks.labelprinter !== undefined)
|
||||
{
|
||||
|
|
@ -171,7 +171,7 @@ $(document).on('click', '.stockentry-grocycode-label-print', function(e)
|
|||
function RefreshStockEntryRow(stockRowId)
|
||||
{
|
||||
Grocy.Api.Get("stock/entry/" + stockRowId,
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
var stockRow = $('#stock-' + stockRowId + '-row');
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ function RefreshStockEntryRow(stockRowId)
|
|||
|
||||
if (result == null || result.amount == 0)
|
||||
{
|
||||
animateCSS("#stock-" + stockRowId + "-row", "fadeOut", function()
|
||||
animateCSS("#stock-" + stockRowId + "-row", "fadeOut", function ()
|
||||
{
|
||||
$("#stock-" + stockRowId + "-row").addClass("d-none");
|
||||
});
|
||||
|
|
@ -225,21 +225,21 @@ function RefreshStockEntryRow(stockRowId)
|
|||
|
||||
var locationName = "";
|
||||
Grocy.Api.Get("objects/locations/" + result.location_id,
|
||||
function(locationResult)
|
||||
function (locationResult)
|
||||
{
|
||||
locationName = locationResult.name;
|
||||
|
||||
$('#stock-' + stockRowId + '-location').attr('data-location-id', result.location_id);
|
||||
$('#stock-' + stockRowId + '-location').text(locationName);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
|
||||
Grocy.Api.Get("stock/products/" + result.product_id,
|
||||
function(productDetails)
|
||||
function (productDetails)
|
||||
{
|
||||
if (!result.price)
|
||||
{
|
||||
|
|
@ -254,7 +254,7 @@ function RefreshStockEntryRow(stockRowId)
|
|||
$(".product-open-button[data-stockrow-id='" + stockRowId + "']").addClass("disabled");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -268,14 +268,14 @@ function RefreshStockEntryRow(stockRowId)
|
|||
{
|
||||
var shoppingLocationName = "";
|
||||
Grocy.Api.Get("objects/shopping_locations/" + result.shopping_location_id,
|
||||
function(shoppingLocationResult)
|
||||
function (shoppingLocationResult)
|
||||
{
|
||||
shoppingLocationName = shoppingLocationResult.name;
|
||||
|
||||
$('#stock-' + stockRowId + '-shopping-location').attr('data-shopping-location-id', result.location_id);
|
||||
$('#stock-' + stockRowId + '-shopping-location').text(shoppingLocationName);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -298,13 +298,13 @@ function RefreshStockEntryRow(stockRowId)
|
|||
}
|
||||
|
||||
// Needs to be delayed because of the animation above the date-text would be wrong if fired immediately...
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
RefreshContextualTimeago("#stock-" + stockRowId + "-row");
|
||||
RefreshLocaleNumberDisplay("#stock-" + stockRowId + "-row");
|
||||
}, Grocy.FormFocusDelay);
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
Grocy.FrontendHelpers.EndUiBusy();
|
||||
console.error(xhr);
|
||||
|
|
@ -312,13 +312,13 @@ function RefreshStockEntryRow(stockRowId)
|
|||
);
|
||||
}
|
||||
|
||||
$(window).on("message", function(e)
|
||||
$(window).on("message", function (e)
|
||||
{
|
||||
var data = e.originalEvent.data;
|
||||
|
||||
if (data.Message == "ProductChanged")
|
||||
{
|
||||
$(".stock-consume-button[data-product-id='" + data.Payload + "']").each(function()
|
||||
$(".stock-consume-button[data-product-id='" + data.Payload + "']").each(function ()
|
||||
{
|
||||
RefreshStockEntryRow($(this).attr("data-stockrow-id"));
|
||||
});
|
||||
|
|
@ -330,12 +330,12 @@ Grocy.Components.ProductPicker.GetPicker().trigger('change');
|
|||
function UndoStockBookingEntry(bookingId, stockRowId, productId)
|
||||
{
|
||||
Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
Grocy.GetTopmostWindow().postMessage(WindowMessageBag("BroadcastMessage", WindowMessageBag("ProductChanged", productId)), Grocy.BaseUrl);
|
||||
toastr.success(__t("Booking successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#stock-journal-table tbody').removeClass("d-none");
|
||||
stockJournalTable.columns.adjust().draw();
|
||||
|
||||
$("#product-filter").on("change", function()
|
||||
$("#product-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -23,7 +23,7 @@ $("#product-filter").on("change", function()
|
|||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#transaction-type-filter").on("change", function()
|
||||
$("#transaction-type-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#transaction-type-filter option:selected").text();
|
||||
|
|
@ -32,10 +32,10 @@ $("#transaction-type-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(4)).search(text).draw();
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(4)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#location-filter").on("change", function()
|
||||
$("#location-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#location-filter option:selected").text();
|
||||
|
|
@ -44,10 +44,10 @@ $("#location-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(5)).search(text).draw();
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(5)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function()
|
||||
$("#user-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#user-filter option:selected").text();
|
||||
|
|
@ -56,16 +56,16 @@ $("#user-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(6)).search(text).draw();
|
||||
stockJournalTable.column(stockJournalTable.colReorder.transpose(6)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#daterange-filter").on("change", function()
|
||||
$("#daterange-filter").on("change", function ()
|
||||
{
|
||||
UpdateUriParam("months", $(this).val());
|
||||
window.location.reload();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -73,10 +73,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
stockJournalTable.search(value).draw();
|
||||
stockJournalTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#transaction-type-filter").val("all");
|
||||
|
|
@ -104,7 +104,7 @@ if (typeof GetUriParam("months") !== "undefined")
|
|||
$("#daterange-filter").val(GetUriParam("months"));
|
||||
}
|
||||
|
||||
$(document).on('click', '.undo-stock-booking-button', function(e)
|
||||
$(document).on('click', '.undo-stock-booking-button', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ $(document).on('click', '.undo-stock-booking-button', function(e)
|
|||
}
|
||||
|
||||
Grocy.Api.Post('stock/bookings/' + bookingId.toString() + '/undo', {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
correspondingBookingsRoot.addClass("text-muted");
|
||||
correspondingBookingsRoot.find("span.name-anchor").addClass("text-strike-through").after("<br>" + __t("Undone on") + " " + moment().format("YYYY-MM-DD HH:mm:ss") + " <time class='timeago timeago-contextual' datetime='" + moment().format("YYYY-MM-DD HH:mm:ss") + "'></time>");
|
||||
|
|
@ -126,7 +126,7 @@ $(document).on('click', '.undo-stock-booking-button', function(e)
|
|||
RefreshContextualTimeago("#stock-booking-" + bookingId + "-row");
|
||||
toastr.success(__t("Booking successfully undone"));
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
toastr.error(__t(JSON.parse(xhr.response).error_message));
|
||||
|
|
@ -134,12 +134,12 @@ $(document).on('click', '.undo-stock-booking-button', function(e)
|
|||
);
|
||||
});
|
||||
|
||||
$(document).on('click', '.product-grocycode-label-print', function(e)
|
||||
$(document).on('click', '.product-grocycode-label-print', function (e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
var productId = $(e.currentTarget).attr('data-product-id');
|
||||
Grocy.Api.Get('stock/products/' + productId + '/printlabel', function(labelData)
|
||||
Grocy.Api.Get('stock/products/' + productId + '/printlabel', function (labelData)
|
||||
{
|
||||
if (Grocy.Webhooks.labelprinter !== undefined)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ var journalSummaryTable = $('#stock-journal-summary-table').DataTable({
|
|||
$('#stock-journal-summary-table tbody').removeClass("d-none");
|
||||
journalSummaryTable.columns.adjust().draw();
|
||||
|
||||
$("#product-filter").on("change", function()
|
||||
$("#product-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#product-filter option:selected").text();
|
||||
|
|
@ -18,11 +18,11 @@ $("#product-filter").on("change", function()
|
|||
}
|
||||
else
|
||||
{
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(1)).search("^" + $.fn.dataTable.util.escapeRegex(text) + "$", true, false).draw();
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(1)).search("^" + $.fn.dataTable.util.escapeRegex(text.accentNeutralise()) + "$", true, false).draw();
|
||||
}
|
||||
});
|
||||
|
||||
$("#transaction-type-filter").on("change", function()
|
||||
$("#transaction-type-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#transaction-type-filter option:selected").text();
|
||||
|
|
@ -31,10 +31,10 @@ $("#transaction-type-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(2)).search(text).draw();
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(2)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function()
|
||||
$("#user-filter").on("change", function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
var text = $("#user-filter option:selected").text();
|
||||
|
|
@ -43,10 +43,10 @@ $("#user-filter").on("change", function()
|
|||
text = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(3)).search(text).draw();
|
||||
journalSummaryTable.column(journalSummaryTable.colReorder.transpose(3)).search(text.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -54,10 +54,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
journalSummaryTable.search(value).draw();
|
||||
journalSummaryTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#transaction-type-filter").val("all");
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ $("#location-filter").on("change", function ()
|
|||
value = "xx" + value + "xx";
|
||||
}
|
||||
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(6)).search(value).draw();
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(6)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#product-group-filter").on("change", function ()
|
||||
|
|
@ -64,7 +64,7 @@ $("#product-group-filter").on("change", function ()
|
|||
value = "xx" + value + "xx";
|
||||
}
|
||||
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(8)).search(value).draw();
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(8)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#status-filter").on("change", function ()
|
||||
|
|
@ -78,7 +78,7 @@ $("#status-filter").on("change", function ()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(7)).search(value).draw();
|
||||
stockOverviewTable.column(stockOverviewTable.colReorder.transpose(7)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$(".status-filter-message").on("click", function ()
|
||||
|
|
@ -108,7 +108,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
stockOverviewTable.search(value).draw();
|
||||
stockOverviewTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$(document).on('click', '.product-grocycode-label-print', function (e)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#taskcategories-table tbody').removeClass("d-none");
|
||||
categoriesTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
categoriesTable.search(value).draw();
|
||||
categoriesTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
categoriesTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.task-category-delete-button', function(e)
|
||||
$(document).on('click', '.task-category-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-category-name');
|
||||
var objectId = $(e.currentTarget).attr('data-category-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.task-category-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/task_categories/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/taskcategories');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ $(document).on('click', '.task-category-delete-button', function(e)
|
|||
});
|
||||
});
|
||||
|
||||
$("#show-disabled").change(function()
|
||||
$("#show-disabled").change(function ()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ $("#search").on("keyup", Delay(function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
tasksTable.search(value).draw();
|
||||
tasksTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#status-filter").on("change", function ()
|
||||
|
|
@ -31,7 +31,7 @@ $("#status-filter").on("change", function ()
|
|||
// Transfer CSS classes of selected element to dropdown element (for background)
|
||||
$(this).attr("class", $("#" + $(this).attr("id") + " option[value='" + value + "']").attr("class") + " form-control");
|
||||
|
||||
tasksTable.column(tasksTable.colReorder.transpose(5)).search(value).draw();
|
||||
tasksTable.column(tasksTable.colReorder.transpose(5)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#user-filter").on("change", function ()
|
||||
|
|
@ -46,7 +46,7 @@ $("#user-filter").on("change", function ()
|
|||
"^" + $.fn.dataTable.util.escapeRegex(value) + "$"
|
||||
}
|
||||
|
||||
tasksTable.column(tasksTable.colReorder.transpose(4)).search(value, true, false).draw();
|
||||
tasksTable.column(tasksTable.colReorder.transpose(4)).search(value.accentNeutralise(), true, false).draw();
|
||||
});
|
||||
|
||||
$("#category-filter").on("change", function ()
|
||||
|
|
@ -57,7 +57,7 @@ $("#category-filter").on("change", function ()
|
|||
value = "";
|
||||
}
|
||||
|
||||
tasksTable.column(tasksTable.colReorder.transpose(3)).search(value).draw();
|
||||
tasksTable.column(tasksTable.colReorder.transpose(3)).search(value.accentNeutralise()).draw();
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#userentities-table tbody').removeClass("d-none");
|
||||
userentitiesTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
userentitiesTable.search(value).draw();
|
||||
userentitiesTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
userentitiesTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.userentity-delete-button', function(e)
|
||||
$(document).on('click', '.userentity-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-userentity-name');
|
||||
var objectId = $(e.currentTarget).attr('data-userentity-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.userentity-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/userentities/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/userentities');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#userfields-table tbody').removeClass("d-none");
|
||||
userfieldsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,10 +16,10 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
userfieldsTable.search(value).draw();
|
||||
userfieldsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#entity-filter").on("change", function()
|
||||
$("#entity-filter").on("change", function ()
|
||||
{
|
||||
var value = $("#entity-filter option:selected").text();
|
||||
if (value === __t("All"))
|
||||
|
|
@ -27,11 +27,11 @@ $("#entity-filter").on("change", function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
userfieldsTable.column(userfieldsTable.colReorder.transpose(1)).search(value).draw();
|
||||
userfieldsTable.column(userfieldsTable.colReorder.transpose(1)).search(value.accentNeutralise()).draw();
|
||||
$("#new-userfield-button").attr("href", U("/userfield/new?embedded&entity=" + value));
|
||||
});
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
$("#entity-filter").val("all");
|
||||
|
|
@ -39,7 +39,7 @@ $("#clear-filter-button").on("click", function()
|
|||
userfieldsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.userfield-delete-button', function(e)
|
||||
$(document).on('click', '.userfield-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-userfield-name');
|
||||
var objectId = $(e.currentTarget).attr('data-userfield-id');
|
||||
|
|
@ -57,16 +57,16 @@ $(document).on('click', '.userfield-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/userfields/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/userfields');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
@ -80,7 +80,7 @@ if (GetUriParam("entity"))
|
|||
{
|
||||
$("#entity-filter").val(GetUriParam("entity"));
|
||||
$("#entity-filter").trigger("change");
|
||||
setTimeout(function()
|
||||
setTimeout(function ()
|
||||
{
|
||||
$("#name").focus();
|
||||
}, Grocy.FormFocusDelay);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ $('#save-user-button').on('click', function (e)
|
|||
jsonData.picture_file_name = RandomString() + CleanFileName($("#user-picture")[0].files[0].name);
|
||||
}
|
||||
|
||||
jsonData.password_base64 = btoa(jsonData.password);
|
||||
jsonData.password_base64 = btoa(String.fromCharCode(...new TextEncoder().encode(jsonData.password)));
|
||||
delete jsonData.password;
|
||||
delete jsonData.password_confirm;
|
||||
delete jsonData.change_password;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('.userobjects-table tbody').removeClass("d-none");
|
||||
userobjectsTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
userobjectsTable.search(value).draw();
|
||||
userobjectsTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
userobjectsTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.userobject-delete-button', function(e)
|
||||
$(document).on('click', '.userobject-delete-button', function (e)
|
||||
{
|
||||
var objectId = $(e.currentTarget).attr('data-userobject-id');
|
||||
|
||||
|
|
@ -42,16 +42,16 @@ $(document).on('click', '.userobject-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('objects/userobjects/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.reload();
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
$('#users-table tbody').removeClass("d-none");
|
||||
usersTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
$("#search").on("keyup", Delay(function ()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
|
|
@ -16,16 +16,16 @@ $("#search").on("keyup", Delay(function()
|
|||
value = "";
|
||||
}
|
||||
|
||||
usersTable.search(value).draw();
|
||||
usersTable.search(value.accentNeutralise()).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
||||
$("#clear-filter-button").on("click", function()
|
||||
$("#clear-filter-button").on("click", function ()
|
||||
{
|
||||
$("#search").val("");
|
||||
usersTable.search("").draw();
|
||||
});
|
||||
|
||||
$(document).on('click', '.user-delete-button', function(e)
|
||||
$(document).on('click', '.user-delete-button', function (e)
|
||||
{
|
||||
var objectName = $(e.currentTarget).attr('data-user-username');
|
||||
var objectId = $(e.currentTarget).attr('data-user-id');
|
||||
|
|
@ -43,16 +43,16 @@ $(document).on('click', '.user-delete-button', function(e)
|
|||
className: 'btn-danger'
|
||||
}
|
||||
},
|
||||
callback: function(result)
|
||||
callback: function (result)
|
||||
{
|
||||
if (result === true)
|
||||
{
|
||||
Grocy.Api.Delete('users/' + objectId, {},
|
||||
function(result)
|
||||
function (result)
|
||||
{
|
||||
window.location.href = U('/users');
|
||||
},
|
||||
function(xhr)
|
||||
function (xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ $app->group('/api', function (RouteCollectorProxy $group)
|
|||
$group->post('/stock/products/{productId}/inventory', [StockApiController::class, 'InventoryProduct']);
|
||||
$group->post('/stock/products/{productId}/open', [StockApiController::class, 'OpenProduct']);
|
||||
$group->post('/stock/products/{productIdToKeep}/merge/{productIdToRemove}', [StockApiController::class, 'MergeProducts']);
|
||||
$group->post('/stock/products/{productId}/copy', [StockApiController::class, 'CopyProduct']);
|
||||
$group->get('/stock/products/by-barcode/{barcode}', [StockApiController::class, 'ProductDetailsByBarcode']);
|
||||
$group->post('/stock/products/by-barcode/{barcode}/add', [StockApiController::class, 'AddProductByBarcode']);
|
||||
$group->post('/stock/products/by-barcode/{barcode}/consume', [StockApiController::class, 'ConsumeProductByBarcode']);
|
||||
|
|
|
|||
|
|
@ -36,20 +36,25 @@ class DatabaseService
|
|||
}
|
||||
}
|
||||
|
||||
if ($params == null)
|
||||
if ($params === null)
|
||||
{
|
||||
|
||||
if ($pdo->exec($sql) === false)
|
||||
{
|
||||
throw new \Exception($pdo->errorInfo());
|
||||
throw new \Exception(implode(' | ', $pdo->errorInfo()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$cmd = $pdo->prepare($sql);
|
||||
|
||||
if ($cmd === false)
|
||||
{
|
||||
throw new \Exception(implode(' | ', $pdo->errorInfo()));
|
||||
}
|
||||
|
||||
if ($cmd->execute($params) === false)
|
||||
{
|
||||
throw new \Exception($pdo->errorInfo());
|
||||
throw new \Exception(implode(' | ', $cmd->errorInfo()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -400,26 +400,24 @@ class StockService extends BaseService
|
|||
|
||||
if ($transactionType === self::TRANSACTION_TYPE_CONSUME || $transactionType === self::TRANSACTION_TYPE_INVENTORY_CORRECTION)
|
||||
{
|
||||
if ($locationId === null)
|
||||
{
|
||||
// Consume from any location
|
||||
$potentialStockEntries = $this->GetProductStockEntries($productId, false, $allowSubproductSubstitution);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Consume only from the supplied location
|
||||
$potentialStockEntries = $this->GetProductStockEntriesForLocation($productId, $locationId, false, $allowSubproductSubstitution);
|
||||
}
|
||||
$potentialStockEntries = $this->GetProductStockEntries($productId, $locationId, false, $allowSubproductSubstitution);
|
||||
|
||||
if ($specificStockEntryId !== 'default')
|
||||
{
|
||||
$potentialStockEntries = FindAllObjectsInArrayByPropertyValue($potentialStockEntries, 'stock_id', $specificStockEntryId);
|
||||
}
|
||||
|
||||
$productStockAmount = $productDetails->stock_amount_aggregated;
|
||||
if (round($amount, 2) > round($productStockAmount, 2))
|
||||
if ($locationId === null)
|
||||
{
|
||||
throw new \Exception('Amount to be consumed cannot be > current stock amount (if supplied, at the desired location)');
|
||||
$productStockAmountTotal = $this->DB->stock()->where('product_id = :1', $productId)->sum('amount');
|
||||
}
|
||||
else
|
||||
{
|
||||
$productStockAmountTotal = $this->DB->stock()->where('product_id = :1 AND location_id = :2', $productId, $locationId)->sum('amount');
|
||||
}
|
||||
if ($amount > $productStockAmountTotal)
|
||||
{
|
||||
throw new \Exception('Amount to be consumed cannot be > current unopened stock amount (if supplied, at the desired location)');
|
||||
}
|
||||
|
||||
if ($transactionId === null)
|
||||
|
|
@ -865,7 +863,7 @@ class StockService extends BaseService
|
|||
return $returnData;
|
||||
}
|
||||
|
||||
public function GetProductStockEntries(int $productId, $excludeOpened = false, $allowSubproductSubstitution = false)
|
||||
public function GetProductStockEntries(int $productId, $locationId = null, $excludeOpened = false, $allowSubproductSubstitution = false)
|
||||
{
|
||||
$sqlWhereProductId = 'product_id = ' . $productId;
|
||||
if ($allowSubproductSubstitution)
|
||||
|
|
@ -879,7 +877,13 @@ class StockService extends BaseService
|
|||
$sqlWhereAndOpen = 'AND open = 0';
|
||||
}
|
||||
|
||||
return $this->DB->stock_next_use()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen);
|
||||
$sqlWhereAndLocationId = '';
|
||||
if ($locationId !== null)
|
||||
{
|
||||
$sqlWhereAndLocationId = 'AND location_id = ' . $locationId;
|
||||
}
|
||||
|
||||
return $this->DB->stock_next_use()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen . ' ' . $sqlWhereAndLocationId);
|
||||
}
|
||||
|
||||
public function GetLocationStockEntries($locationId)
|
||||
|
|
@ -892,12 +896,6 @@ class StockService extends BaseService
|
|||
return $this->DB->stock()->where('location_id', $locationId);
|
||||
}
|
||||
|
||||
public function GetProductStockEntriesForLocation($productId, $locationId, $excludeOpened = false, $allowSubproductSubstitution = false)
|
||||
{
|
||||
$stockEntries = $this->GetProductStockEntries($productId, $excludeOpened, $allowSubproductSubstitution);
|
||||
return FindAllObjectsInArrayByPropertyValue($stockEntries, 'location_id', $locationId);
|
||||
}
|
||||
|
||||
public function GetProductStockLocations(int $productId, $allowSubproductSubstitution = false)
|
||||
{
|
||||
$sqlWhereProductId = 'product_id = ' . $productId;
|
||||
|
|
@ -978,7 +976,7 @@ class StockService extends BaseService
|
|||
return null;
|
||||
}
|
||||
|
||||
public function OpenProduct(int $productId, float $amount, $specificStockEntryId = 'default', &$transactionId = null, $allowSubproductSubstitution = false)
|
||||
public function OpenProduct(int $productId, float $amount, $locationId = null, $specificStockEntryId = 'default', &$transactionId = null, $allowSubproductSubstitution = false)
|
||||
{
|
||||
if (!$this->ProductExists($productId))
|
||||
{
|
||||
|
|
@ -993,17 +991,24 @@ class StockService extends BaseService
|
|||
}
|
||||
|
||||
$productDetails = (object)$this->GetProductDetails($productId);
|
||||
$productStockAmountUnopened = $productDetails->stock_amount_aggregated - $productDetails->stock_amount_opened_aggregated;
|
||||
$potentialStockEntries = $this->GetProductStockEntries($productId, true, $allowSubproductSubstitution);
|
||||
$potentialStockEntries = $this->GetProductStockEntries($productId, $locationId, true, $allowSubproductSubstitution);
|
||||
|
||||
if ($product->enable_tare_weight_handling == 1)
|
||||
{
|
||||
throw new \Exception('Opening tare weight handling enabled products is not supported');
|
||||
}
|
||||
|
||||
if ($locationId === null)
|
||||
{
|
||||
$productStockAmountUnopened = $this->DB->stock()->where('product_id = :1 AND open = 0', $productId)->sum('amount');
|
||||
}
|
||||
else
|
||||
{
|
||||
$productStockAmountUnopened = $this->DB->stock()->where('product_id = :1 AND open = 0 AND location_id = :2', $productId, $locationId)->sum('amount');
|
||||
}
|
||||
if ($amount > $productStockAmountUnopened)
|
||||
{
|
||||
throw new \Exception('Amount to be opened cannot be > current unopened stock amount');
|
||||
throw new \Exception('Amount to be opened cannot be > current unopened stock amount (if supplied, at the desired location)');
|
||||
}
|
||||
|
||||
if ($specificStockEntryId !== 'default')
|
||||
|
|
@ -1290,16 +1295,10 @@ class StockService extends BaseService
|
|||
{
|
||||
// Hard fail for now, as we not yet support transferring tare weight enabled products
|
||||
throw new \Exception('Transferring tare weight enabled products is not yet possible');
|
||||
if ($amount < $productDetails->product->tare_weight)
|
||||
{
|
||||
throw new \Exception('The amount cannot be lower than the defined tare weight');
|
||||
}
|
||||
|
||||
$amount = abs($amount - $productDetails->stock_amount - $productDetails->product->tare_weight);
|
||||
}
|
||||
|
||||
$productStockAmountAtFromLocation = $this->DB->stock()->where('product_id = :1 AND location_id = :2', $productId, $locationIdFrom)->sum('amount');
|
||||
$potentialStockEntriesAtFromLocation = $this->GetProductStockEntriesForLocation($productId, $locationIdFrom);
|
||||
$potentialStockEntriesAtFromLocation = $this->GetProductStockEntries($productId, $locationIdFrom);
|
||||
|
||||
if ($amount > $productStockAmountAtFromLocation)
|
||||
{
|
||||
|
|
@ -1730,6 +1729,54 @@ class StockService extends BaseService
|
|||
DatabaseService::GetInstance()->GetDbConnectionRaw()->commit();
|
||||
}
|
||||
|
||||
public function CopyProduct(int $productId)
|
||||
{
|
||||
if (!$this->ProductExists($productId))
|
||||
{
|
||||
throw new \Exception('Product does not exist');
|
||||
}
|
||||
|
||||
$newName = LocalizationService::GetInstance()->__t('Copy of %s', $this->DB->products($productId)->name);
|
||||
|
||||
DatabaseService::GetInstance()->ExecuteDbStatement(
|
||||
'INSERT INTO products
|
||||
(name, description, product_group_id, active, location_id, shopping_location_id, qu_id_purchase, qu_id_stock, min_stock_amount,
|
||||
default_best_before_days, default_best_before_days_after_open, default_best_before_days_after_freezing,
|
||||
default_best_before_days_after_thawing, picture_file_name, enable_tare_weight_handling, tare_weight, not_check_stock_fulfillment_for_recipes,
|
||||
parent_product_id, calories, cumulate_min_stock_amount_of_sub_products, due_type, quick_consume_amount, hide_on_stock_overview, default_stock_label_type,
|
||||
should_not_be_frozen, treat_opened_as_out_of_stock, no_own_stock, default_consume_location_id, move_on_open, row_created_timestamp, qu_id_consume,
|
||||
auto_reprint_stock_label, quick_open_amount, qu_id_price, disable_open, default_purchase_price_type)
|
||||
SELECT :new_name, description, product_group_id, active, location_id, shopping_location_id, qu_id_purchase, qu_id_stock, min_stock_amount,
|
||||
default_best_before_days, default_best_before_days_after_open, default_best_before_days_after_freezing,
|
||||
default_best_before_days_after_thawing, picture_file_name, enable_tare_weight_handling, tare_weight, not_check_stock_fulfillment_for_recipes,
|
||||
parent_product_id, calories, cumulate_min_stock_amount_of_sub_products, due_type, quick_consume_amount, hide_on_stock_overview, default_stock_label_type,
|
||||
should_not_be_frozen, treat_opened_as_out_of_stock, no_own_stock, default_consume_location_id, move_on_open, row_created_timestamp, qu_id_consume,
|
||||
auto_reprint_stock_label, quick_open_amount, qu_id_price, disable_open, default_purchase_price_type
|
||||
FROM products
|
||||
WHERE id = :product_id',
|
||||
['product_id' => $productId, 'new_name' => $newName]
|
||||
);
|
||||
$lastInsertId = $this->DB->lastInsertId();
|
||||
|
||||
DatabaseService::GetInstance()->ExecuteDbStatement(
|
||||
'INSERT INTO quantity_unit_conversions
|
||||
(product_id, from_qu_id, to_qu_id, factor)
|
||||
SELECT :last_insert_id, from_qu_id, to_qu_id, factor
|
||||
FROM quantity_unit_conversions q
|
||||
WHERE q.product_id = :product_id
|
||||
AND q.id = (
|
||||
SELECT MIN(q2.id)
|
||||
FROM quantity_unit_conversions q2
|
||||
WHERE q2.product_id = q.product_id
|
||||
AND MIN(q2.from_qu_id, q2.to_qu_id) = MIN(q.from_qu_id, q.to_qu_id)
|
||||
AND MAX(q2.from_qu_id, q2.to_qu_id) = MAX(q.from_qu_id, q.to_qu_id)
|
||||
)', // The corresponding inverse conversion is automatically created by a trigger
|
||||
['product_id' => $productId, 'last_insert_id' => $lastInsertId]
|
||||
);
|
||||
|
||||
return $lastInsertId;
|
||||
}
|
||||
|
||||
public function CompactStockEntries($productId = null)
|
||||
{
|
||||
if ($productId == null)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"Version": "4.7.0",
|
||||
"ReleaseDate": "2026-08-28"
|
||||
"Version": "4.7.1",
|
||||
"ReleaseDate": "2026-09-04"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,9 +160,10 @@
|
|||
<i class="fa-solid fa-ellipsis-v"></i>
|
||||
</button>
|
||||
<div class="table-inline-menu dropdown-menu dropdown-menu-right">
|
||||
<a class="dropdown-item"
|
||||
<a class="dropdown-item product-copy-button"
|
||||
data-product-id="{{ $product->id }}"
|
||||
type="button"
|
||||
href="{{ $U('/product/new?copy-of=') }}{{ $product->id }}">
|
||||
href="#">
|
||||
<span class="dropdown-item-text">{{ $__t('Copy') }}</span>
|
||||
</a>
|
||||
<a class="dropdown-item merge-products-button"
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@
|
|||
type="button"
|
||||
href="#"
|
||||
data-recipe-id="{{ $recipe->id }}">
|
||||
<span class="dropdown-item-text">{{ $__t('Copy recipe') }}</span>
|
||||
<span class="dropdown-item-text">{{ $__t('Copy') }}</span>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item"
|
||||
|
|
|
|||
|
|
@ -275,9 +275,9 @@ summernote@^0.9.1:
|
|||
integrity sha512-5Hfuey6+N0XIbk8ZpkGEVDmrkRVRHZWKBhw/072i9/TJLaWUKboB+KOyyd6AzDP2CQs1O6or4zRTU8HY30kt4w==
|
||||
|
||||
swagger-ui-dist@^5.2.0:
|
||||
version "5.32.14"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.32.14.tgz#bb3a3e738bf17bc2ee2640a711fcc44be76fde4c"
|
||||
integrity sha512-nOA2pSQhcmODMUQZpJHYKNuwniDUqcOWGNaSCOoZv12FdOSJ9JxV95HtyRGNMqEBj6h6lCNTy20TgZDYTSuUIg==
|
||||
version "5.32.15"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.32.15.tgz#0bbaa62695104dbf2db06ad9bbbaaa127d830614"
|
||||
integrity sha512-TSFER+rFQlf1nzk6WvKkMaHTxAPQ3eAAxigFThnxQedSREanfZgSbJFayZVs/ULnSbNdrJOb99vLD6xpb3R3eg==
|
||||
dependencies:
|
||||
"@scarf/scarf" "=1.4.0"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user