mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 01:32:38 +00:00
Filtering of API-Results (#985)
* Add FilteredApiResponse * Use FilteredApiResponse for Generic-Entity-Search * Use FilteredApiResponse for Recipe-Fullfillment * Use FilteredApiResponse for GetUsers * Use FilteredApiResponse for current Tasks * Use FilteredApiResponse for ProductStockEntries & ProductStockLocations * Use FilteredApiResponse for current chores * Use FilteredApiResponse for batteries-current * Fix missing highlighting of "< X days" * Keep to use existing views Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
parent
60f3d900e8
commit
32a4f81f62
@ -2,10 +2,16 @@
|
||||
|
||||
namespace Grocy\Controllers;
|
||||
|
||||
use LessQL\Result;
|
||||
|
||||
class BaseApiController extends BaseController
|
||||
{
|
||||
protected $OpenApiSpec = null;
|
||||
|
||||
const PATTERN_FIELD = '[A-Za-z_][A-Za-z0-9_]+';
|
||||
const PATTERN_OPERATOR = '!?(=|~|<|>|(>=)|(<=))';
|
||||
const PATTERN_VALUE = '[A-Za-z_0-9.]+';
|
||||
|
||||
public function __construct(\DI\Container $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
@ -29,6 +35,68 @@ class BaseApiController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
public function FilteredApiResponse(\Psr\Http\Message\ResponseInterface $response, Result $data, array $query)
|
||||
{
|
||||
$data = $this->queryData($data, $query);
|
||||
return $this->ApiResponse($response, $data);
|
||||
}
|
||||
|
||||
protected function queryData(Result $data, array $query)
|
||||
{
|
||||
if (isset($query['query']))
|
||||
$data = $this->filter($data, $query['query']);
|
||||
if (isset($query['limit']))
|
||||
$data = $data->limit(intval($query['limit']), intval($query['offset'] ?? 0));
|
||||
if (isset($query['order']))
|
||||
$data = $data->orderBy($query['order']);
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function filter(Result $data, array $query): Result
|
||||
{
|
||||
foreach ($query as $q) {
|
||||
$matches = array();
|
||||
preg_match('/(?P<field>' . self::PATTERN_FIELD . ')'
|
||||
. '(?P<op>' . self::PATTERN_OPERATOR . ')'
|
||||
. '(?P<value>' . self::PATTERN_VALUE . ')/',
|
||||
$q, $matches
|
||||
);
|
||||
error_log(var_export($matches, true));
|
||||
switch ($matches['op']) {
|
||||
case '=':
|
||||
$data = $data->where($matches['field'], $matches['value']);
|
||||
break;
|
||||
case '!=':
|
||||
$data = $data->whereNot($matches['field'], $matches['value']);
|
||||
break;
|
||||
case '~':
|
||||
$data = $data->where($matches['field'] . ' LIKE ?', '%' . $matches['value'] . '%');
|
||||
break;
|
||||
case '!~':
|
||||
$data = $data->where($matches['field'] . ' NOT LIKE ?', '%' . $matches['value'] . '%');
|
||||
break;
|
||||
case '!>=':
|
||||
case '<':
|
||||
$data = $data->where($matches['field'] . ' < ?', $matches['value']);
|
||||
break;
|
||||
case '!<=':
|
||||
case '>':
|
||||
$data = $data->where($matches['field'] . ' > ?', $matches['value']);
|
||||
break;
|
||||
case '!<':
|
||||
case '>=':
|
||||
$data = $data->where($matches['field'] . ' >= ?', $matches['value']);
|
||||
break;
|
||||
case '!>':
|
||||
case '<=':
|
||||
$data = $data->where($matches['field'] . ' <= ?', $matches['value']);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function getOpenApispec()
|
||||
{
|
||||
if ($this->OpenApiSpec == null)
|
||||
|
@ -21,7 +21,7 @@ class BatteriesApiController extends BaseApiController
|
||||
|
||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getBatteriesService()->GetCurrent());
|
||||
return $this->FilteredApiResponse($response, $this->getBatteriesService()->GetCurrent(), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function TrackChargeCycle(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
|
@ -58,7 +58,7 @@ class ChoresApiController extends BaseApiController
|
||||
|
||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getChoresService()->GetCurrent());
|
||||
return $this->FilteredApiResponse($response, $this->getChoresService()->GetCurrent(), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function TrackChoreExecution(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Grocy\Controllers;
|
||||
|
||||
use Grocy\Controllers\Users\User;
|
||||
use Slim\Exception\HttpBadRequestException;
|
||||
|
||||
class GenericEntityApiController extends BaseApiController
|
||||
{
|
||||
@ -178,12 +179,13 @@ class GenericEntityApiController extends BaseApiController
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getDatabase()->{$args['entity']}
|
||||
()->where('name LIKE ?', '%' . $args['searchString'] . '%'));
|
||||
return $this->FilteredApiResponse($response, $this->getDatabase()->{$args['entity']}
|
||||
()->where('name LIKE ?', '%' . $args['searchString'] . '%'), $request->getQueryParams());
|
||||
}
|
||||
catch (\PDOException $ex)
|
||||
{
|
||||
return $this->GenericErrorResponse($response, 'The given entity has no field "name"');
|
||||
throw new HttpBadRequestException($request, $ex->getMessage(), $ex);
|
||||
//return $this->GenericErrorResponse($response, 'The given entity has no field "name"', $ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class RecipesApiController extends BaseApiController
|
||||
{
|
||||
if (!isset($args['recipeId']))
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getRecipesService()->GetRecipesResolved());
|
||||
return $this->FilteredApiResponse($response, $this->getRecipesService()->GetRecipesResolved(), $request->getQueryParams());
|
||||
}
|
||||
|
||||
$recipeResolved = FindObjectInArrayByPropertyValue($this->getRecipesService()->GetRecipesResolved(), 'recipe_id', $args['recipeId']);
|
||||
|
@ -552,12 +552,12 @@ class StockApiController extends BaseApiController
|
||||
$allowSubproductSubstitution = true;
|
||||
}
|
||||
|
||||
return $this->ApiResponse($response, $this->getStockService()->GetProductStockEntries($args['productId'], false, $allowSubproductSubstitution));
|
||||
return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockEntries($args['productId'], false, $allowSubproductSubstitution, false), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function ProductStockLocations(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getStockService()->GetProductStockLocations($args['productId']));
|
||||
return $this->FilteredApiResponse($response, $this->getStockService()->GetProductStockLocations($args['productId']), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function RemoveProductFromShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
|
@ -8,7 +8,7 @@ class TasksApiController extends BaseApiController
|
||||
{
|
||||
public function Current(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getTasksService()->GetCurrent());
|
||||
return $this->FilteredApiResponse($response, $this->getTasksService()->GetCurrent(), $request->getQueryParams());
|
||||
}
|
||||
|
||||
public function MarkTaskAsCompleted(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
|
||||
|
@ -123,7 +123,7 @@ class UsersApiController extends BaseApiController
|
||||
User::checkPermission($request, User::PERMISSION_USERS_READ);
|
||||
try
|
||||
{
|
||||
return $this->ApiResponse($response, $this->getUsersService()->GetUsersAsDto());
|
||||
return $this->FilteredApiResponse($response, $this->getUsersService()->GetUsersAsDto(), $request->getQueryParams());
|
||||
}
|
||||
catch (\Exception $ex)
|
||||
{
|
||||
|
92
migrations/0114.sql
Normal file
92
migrations/0114.sql
Normal file
@ -0,0 +1,92 @@
|
||||
CREATE VIEW users_dto
|
||||
AS
|
||||
SELECT
|
||||
id,
|
||||
username,
|
||||
first_name,
|
||||
last_name,
|
||||
row_created_timestamp,
|
||||
(CASE
|
||||
WHEN IFNULL(first_name, '') = '' AND IFNULL(last_name, '') != '' THEN last_name
|
||||
WHEN IFNULL(last_name, '') = '' AND IFNULL(first_name, '') != '' THEN first_name
|
||||
WHEN IFNULL(last_name, '') != '' AND IFNULL(first_name, '') != '' THEN first_name + ' ' + last_name
|
||||
ELSE username
|
||||
END
|
||||
) AS display_name
|
||||
FROM users;
|
||||
|
||||
DROP VIEW chores_current;
|
||||
CREATE VIEW chores_current
|
||||
AS
|
||||
SELECT
|
||||
x.chore_id AS id, -- Dummy, LessQL needs an id column
|
||||
x.chore_id,
|
||||
x.chore_name,
|
||||
x.last_tracked_time,
|
||||
CASE WHEN x.rollover = 1 AND DATETIME('now', 'localtime') > x.next_estimated_execution_time THEN
|
||||
DATETIME(STRFTIME('%Y-%m-%d', DATETIME('now', 'localtime')) || ' ' || STRFTIME('%H:%M:%S', x.next_estimated_execution_time))
|
||||
ELSE
|
||||
x.next_estimated_execution_time
|
||||
END AS next_estimated_execution_time,
|
||||
x.track_date_only,
|
||||
x.next_execution_assigned_to_user_id
|
||||
FROM (
|
||||
|
||||
SELECT
|
||||
h.id AS chore_id,
|
||||
h.name AS chore_name,
|
||||
MAX(l.tracked_time) AS last_tracked_time,
|
||||
CASE h.period_type
|
||||
WHEN 'manually' THEN '2999-12-31 23:59:59'
|
||||
WHEN 'dynamic-regular' THEN DATETIME(MAX(l.tracked_time), '+' || CAST(h.period_days AS TEXT) || ' day')
|
||||
WHEN 'daily' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+' || CAST(h.period_interval AS TEXT) || ' day')
|
||||
WHEN 'weekly' THEN (
|
||||
SELECT next
|
||||
FROM (
|
||||
SELECT 'sunday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 0') AS next
|
||||
UNION
|
||||
SELECT 'monday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 1') AS next
|
||||
UNION
|
||||
SELECT 'tuesday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 2') AS next
|
||||
UNION
|
||||
SELECT 'wednesday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 3') AS next
|
||||
UNION
|
||||
SELECT 'thursday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 4') AS next
|
||||
UNION
|
||||
SELECT 'friday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 5') AS next
|
||||
UNION
|
||||
SELECT 'saturday' AS day, DATETIME(COALESCE((SELECT tracked_time FROM chores_log WHERE chore_id = h.id ORDER BY tracked_time DESC LIMIT 1), DATETIME('now', 'localtime')), '1 days', '+' || CAST((h.period_interval - 1) * 7 AS TEXT) || ' days', 'weekday 6') AS next
|
||||
)
|
||||
WHERE INSTR(period_config, day) > 0
|
||||
ORDER BY next
|
||||
LIMIT 1
|
||||
)
|
||||
WHEN 'monthly' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+' || CAST(h.period_interval AS TEXT) || ' month', 'start of month', '+' || CAST(h.period_days - 1 AS TEXT) || ' day')
|
||||
WHEN 'yearly' THEN DATETIME(IFNULL(MAX(l.tracked_time), DATETIME('now', 'localtime')), '+' || CAST(h.period_interval AS TEXT) || ' years')
|
||||
END AS next_estimated_execution_time,
|
||||
h.track_date_only,
|
||||
h.rollover,
|
||||
h.next_execution_assigned_to_user_id
|
||||
FROM chores h
|
||||
LEFT JOIN chores_log l
|
||||
ON h.id = l.chore_id
|
||||
AND l.undone = 0
|
||||
GROUP BY h.id, h.name, h.period_days
|
||||
|
||||
) x;
|
||||
|
||||
DROP VIEW batteries_current;
|
||||
CREATE VIEW batteries_current
|
||||
AS
|
||||
SELECT
|
||||
b.id, -- Dummy, LessQL needs an id column
|
||||
b.id AS battery_id,
|
||||
MAX(l.tracked_time) AS last_tracked_time,
|
||||
CASE WHEN b.charge_interval_days = 0
|
||||
THEN '2999-12-31 23:59:59'
|
||||
ELSE datetime(MAX(l.tracked_time), '+' || CAST(b.charge_interval_days AS TEXT) || ' day')
|
||||
END AS next_estimated_charge_time
|
||||
FROM batteries b
|
||||
LEFT JOIN battery_charge_cycles l
|
||||
ON b.id = l.battery_id
|
||||
GROUP BY b.id, b.charge_interval_days;
|
@ -153,7 +153,7 @@ $app->group('/api', function(RouteCollectorProxy $group)
|
||||
// Generic entity interaction
|
||||
$group->get('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:GetObjects');
|
||||
$group->get('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:GetObject');
|
||||
$group->get('/objects/{entity}/search/{searchString}', '\Grocy\Controllers\GenericEntityApiController:SearchObjects');
|
||||
$group->get('/objects/{entity}/search/{searchString:.*}', '\Grocy\Controllers\GenericEntityApiController:SearchObjects');
|
||||
$group->post('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:AddObject');
|
||||
$group->put('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:EditObject');
|
||||
$group->delete('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:DeleteObject');
|
||||
|
@ -26,8 +26,7 @@ class BatteriesService extends BaseService
|
||||
|
||||
public function GetCurrent()
|
||||
{
|
||||
$sql = 'SELECT * from batteries_current';
|
||||
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
return $this->getDatabase()->batteries_current();
|
||||
}
|
||||
|
||||
public function TrackChargeCycle(int $batteryId, string $trackedTime)
|
||||
|
@ -152,8 +152,7 @@ class ChoresService extends BaseService
|
||||
|
||||
public function GetCurrent()
|
||||
{
|
||||
$sql = 'SELECT chores_current.*, chores.name AS chore_name from chores_current join chores on chores_current.chore_id = chores.id';
|
||||
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
return $this->getDatabase()->chores_current();
|
||||
}
|
||||
|
||||
public function TrackChore(int $choreId, string $trackedTime, $doneBy = GROCY_USER_ID)
|
||||
|
@ -4,6 +4,8 @@ namespace Grocy\Services;
|
||||
|
||||
#use \Grocy\Services\StockService;
|
||||
|
||||
use LessQL\Result;
|
||||
|
||||
class RecipesService extends BaseService
|
||||
{
|
||||
const RECIPE_TYPE_MEALPLAN_DAY = 'mealplan-day';
|
||||
@ -82,10 +84,9 @@ class RecipesService extends BaseService
|
||||
return $this->getDataBaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function GetRecipesResolved()
|
||||
public function GetRecipesResolved(): Result
|
||||
{
|
||||
$sql = 'SELECT * FROM recipes_resolved';
|
||||
return $this->getDataBaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
return $this->getDatabase()->recipes_resolved();
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
|
@ -603,7 +603,7 @@ class StockService extends BaseService
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function GetProductStockEntries($productId, $excludeOpened = false, $allowSubproductSubstitution = false)
|
||||
public function GetProductStockEntries($productId, $excludeOpened = false, $allowSubproductSubstitution = false, $ordered = true)
|
||||
{
|
||||
// In order of next use:
|
||||
// First expiring first, then first in first out
|
||||
@ -621,8 +621,10 @@ class StockService extends BaseService
|
||||
{
|
||||
$sqlWhereAndOpen = 'AND open = 0';
|
||||
}
|
||||
|
||||
return $this->getDatabase()->stock()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen, $productId)->orderBy('best_before_date', 'ASC')->orderBy('purchased_date', 'ASC')->fetchAll();
|
||||
$result = $this->getDatabase()->stock()->where($sqlWhereProductId . ' ' . $sqlWhereAndOpen, $productId);
|
||||
if ($ordered)
|
||||
return $result->orderBy('best_before_date', 'ASC')->orderBy('purchased_date', 'ASC');
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function GetProductStockEntriesForLocation($productId, $locationId, $excludeOpened = false, $allowSubproductSubstitution = false)
|
||||
@ -633,7 +635,7 @@ class StockService extends BaseService
|
||||
|
||||
public function GetProductStockLocations($productId)
|
||||
{
|
||||
return $this->getDatabase()->stock_current_locations()->where('product_id', $productId)->fetchAll();
|
||||
return $this->getDatabase()->stock_current_locations()->where('product_id', $productId);
|
||||
}
|
||||
|
||||
public function GetStockEntry($entryId)
|
||||
|
@ -4,10 +4,9 @@ namespace Grocy\Services;
|
||||
|
||||
class TasksService extends BaseService
|
||||
{
|
||||
public function GetCurrent()
|
||||
public function GetCurrent(): \LessQL\Result
|
||||
{
|
||||
$sql = 'SELECT * from tasks_current';
|
||||
return $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
return $this->getDatabase()->tasks_current();
|
||||
}
|
||||
|
||||
public function MarkTaskAsCompleted($taskId, $doneTime)
|
||||
|
@ -81,19 +81,9 @@ class UsersService extends BaseService
|
||||
return array_merge($GROCY_DEFAULT_USER_SETTINGS, $settings);
|
||||
}
|
||||
|
||||
public function GetUsersAsDto()
|
||||
public function GetUsersAsDto(): \LessQL\Result
|
||||
{
|
||||
$users = $this->getDatabase()->users();
|
||||
$returnUsers = [];
|
||||
|
||||
foreach ($users as $user)
|
||||
{
|
||||
unset($user->password);
|
||||
$user->display_name = GetUserDisplayName($user);
|
||||
$returnUsers[] = $user;
|
||||
}
|
||||
|
||||
return $returnUsers;
|
||||
return $this->getDatabase()->users_dto();
|
||||
}
|
||||
|
||||
public function SetUserSetting($userId, $settingKey, $settingValue)
|
||||
|
@ -80,9 +80,7 @@
|
||||
<tbody class="d-none">
|
||||
@foreach($current as $currentBatteryEntry)
|
||||
<tr id="battery-{{ $currentBatteryEntry->battery_id }}-row"
|
||||
class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("
|
||||
+$nextXDays
|
||||
days")))
|
||||
class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days")))
|
||||
table-warning
|
||||
@endif">
|
||||
<td class="fit-content border-right">
|
||||
@ -149,8 +147,7 @@
|
||||
,
|
||||
$currentBatteryEntry->battery_id)->charge_interval_days > 0 && $currentBatteryEntry->next_estimated_charge_time < date('Y-m-d
|
||||
H:i:s',
|
||||
strtotime("+$nextXDays
|
||||
days")))
|
||||
strtotime("+$nextXDays days")))
|
||||
duesoon
|
||||
@endif
|
||||
</td>
|
||||
|
@ -110,9 +110,7 @@
|
||||
<tbody class="d-none">
|
||||
@foreach($currentChores as $curentChoreEntry)
|
||||
<tr id="chore-{{ $curentChoreEntry->chore_id }}-row"
|
||||
class="@if(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("
|
||||
+$nextXDays
|
||||
days")))
|
||||
class="@if(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days")))
|
||||
table-warning
|
||||
@endif">
|
||||
<td class="fit-content border-right">
|
||||
@ -191,8 +189,7 @@
|
||||
,
|
||||
$curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_PERIOD_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d
|
||||
H:i:s',
|
||||
strtotime("+$nextXDays
|
||||
days")))
|
||||
strtotime("+$nextXDays days")))
|
||||
duesoon
|
||||
@endif
|
||||
</td>
|
||||
|
@ -54,9 +54,7 @@
|
||||
<tbody class="d-none">
|
||||
@foreach($stockEntries as $stockEntry)
|
||||
<tr id="stock-{{ $stockEntry->id }}-row"
|
||||
class="@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $stockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $stockEntry->amount > 0) table-danger @elseif(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $stockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("
|
||||
+$nextXDays
|
||||
days"))
|
||||
class="@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $stockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $stockEntry->amount > 0) table-danger @elseif(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $stockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("+$nextXDays days"))
|
||||
&&
|
||||
$stockEntry->amount > 0) table-warning @endif">
|
||||
<td class="fit-content border-right">
|
||||
|
@ -142,9 +142,7 @@
|
||||
<tbody class="d-none">
|
||||
@foreach($currentStock as $currentStockEntry)
|
||||
<tr id="product-{{ $currentStockEntry->product_id }}-row"
|
||||
class="@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $currentStockEntry->amount > 0) table-danger @elseif(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("
|
||||
+$nextXDays
|
||||
days"))
|
||||
class="@if(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime('-1 days')) && $currentStockEntry->amount > 0) table-danger @elseif(GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING && $currentStockEntry->best_before_date < date('Y-m-d 23:59:59', strtotime("+$nextXDays days"))
|
||||
&&
|
||||
$currentStockEntry->amount > 0) table-warning @elseif ($currentStockEntry->product_missing) table-info @endif">
|
||||
<td class="fit-content border-right">
|
||||
@ -324,8 +322,7 @@
|
||||
&&
|
||||
$currentStockEntry->amount > 0) expired @elseif($currentStockEntry->best_before_date < date('Y-m-d
|
||||
23:59:59',
|
||||
strtotime("+$nextXDays
|
||||
days"))
|
||||
strtotime("+$nextXDays days"))
|
||||
&&
|
||||
$currentStockEntry->amount > 0) expiring @endif @if($currentStockEntry->product_missing) belowminstockamount @endif
|
||||
</td>
|
||||
|
@ -156,8 +156,7 @@
|
||||
@if($task->done == 1) text-muted @endif @if(!empty($task->due_date) && $task->due_date < date('Y-m-d'))
|
||||
overdue
|
||||
@elseif(!empty($task->due_date) && $task->due_date < date('Y-m-d',
|
||||
strtotime("+$nextXDays
|
||||
days")))
|
||||
strtotime("+$nextXDays days")))
|
||||
duesoon
|
||||
@endif
|
||||
</td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user