Compare commits

...

8 Commits

Author SHA1 Message Date
Bernd Bestel
ecf96252b9 Add possibility to filter products by location (references #10) 2018-07-08 15:16:24 +02:00
Bernd Bestel
92e648490a Sort all dropdowns 2018-07-08 13:59:42 +02:00
Bernd Bestel
6dd3c26ddd Fix Bower (for now, need to switch to Yarn soon) 2018-07-08 13:51:29 +02:00
Bernd Bestel
02ea26b090 Disable pagination for data tables 2018-07-08 13:50:52 +02:00
Bernd Bestel
0954b5a741 Add option to not use URL rewriting 2018-06-15 20:50:40 +02:00
Bernd Bestel
02b6c3b721 Make it also possible to directly execute/track battery charge cycles and habits from overview pages 2018-05-13 09:38:22 +02:00
Bernd Bestel
6fa4e13ba2 Fix API version display 2018-05-13 09:00:14 +02:00
Bernd Bestel
9837f79f9c Make it also possible to consume the whole stock of a product from stock overview 2018-05-13 08:42:45 +02:00
33 changed files with 277 additions and 107 deletions

View File

@@ -1,3 +1,8 @@
{ {
"directory": "public/bower_components" "directory": "public/bower_components",
"registry": {
"search": [
"https://registry.bower.io"
]
}
} }

View File

@@ -17,6 +17,8 @@ Default login is user `admin` with password `admin` - see the `data/config.php`
If you use nginx as your webserver, please include `try_files $uri /index.php;` in your location block. If you use nginx as your webserver, please include `try_files $uri /index.php;` in your location block.
If, however, your webserver does not support URL rewriting, set `DISABLE_URL_REWRITING` in `data/config.php`.
## How to update ## How to update
Just overwrite everything with the latest release while keeping the `/data` directory, check `config-dist.php` for new configuration options and add them to your `data/config.php` (it will show up as an error if something is missing there). Just overwrite everything with the latest release while keeping the `/data` directory, check `config-dist.php` for new configuration options and add them to your `data/config.php` (it will show up as an error if something is missing there).

View File

@@ -20,3 +20,7 @@ define('BASE_URL', '/');
# must be the filename without .php extension and must be located in /data/plugins, # must be the filename without .php extension and must be located in /data/plugins,
# see /data/plugins/DemoBarcodeLookupPlugin.php for an example implementation # see /data/plugins/DemoBarcodeLookupPlugin.php for an example implementation
define('STOCK_BARCODE_LOOKUP_PLUGIN', 'DemoBarcodeLookupPlugin'); define('STOCK_BARCODE_LOOKUP_PLUGIN', 'DemoBarcodeLookupPlugin');
# If, however, your webserver does not support URL rewriting,
# set this to true
define('DISABLE_URL_REWRITING', false);

View File

@@ -23,9 +23,9 @@ class BaseController
{ {
return $localizationService->Localize($text, ...$placeholderValues); return $localizationService->Localize($text, ...$placeholderValues);
}); });
$container->view->set('U', function($relativePath) use($container) $container->view->set('U', function($relativePath, $isResource = false) use($container)
{ {
return $container->UrlManager->ConstructUrl($relativePath); return $container->UrlManager->ConstructUrl($relativePath, $isResource);
}); });
$this->AppContainer = $container; $this->AppContainer = $container;

View File

@@ -26,7 +26,7 @@ class BatteriesController extends BaseController
$countDueNextXDays = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<')); $countDueNextXDays = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<'));
$countOverdue = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime('-1 days')), '<')); $countOverdue = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime('-1 days')), '<'));
return $this->AppContainer->view->render($response, 'batteriesoverview', [ return $this->AppContainer->view->render($response, 'batteriesoverview', [
'batteries' => $this->Database->batteries(), 'batteries' => $this->Database->batteries()->orderBy('name'),
'current' => $this->BatteriesService->GetCurrent(), 'current' => $this->BatteriesService->GetCurrent(),
'nextChargeTimes' => $nextChargeTimes, 'nextChargeTimes' => $nextChargeTimes,
'nextXDays' => $nextXDays, 'nextXDays' => $nextXDays,
@@ -38,14 +38,14 @@ class BatteriesController extends BaseController
public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'batterytracking', [ return $this->AppContainer->view->render($response, 'batterytracking', [
'batteries' => $this->Database->batteries() 'batteries' => $this->Database->batteries()->orderBy('name')
]); ]);
} }
public function BatteriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function BatteriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'batteries', [ return $this->AppContainer->view->render($response, 'batteries', [
'batteries' => $this->Database->batteries() 'batteries' => $this->Database->batteries()->orderBy('name')
]); ]);
} }

View File

@@ -26,7 +26,7 @@ class HabitsController extends BaseController
$countDueNextXDays = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<')); $countDueNextXDays = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<'));
$countOverdue = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime('-1 days')), '<')); $countOverdue = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime('-1 days')), '<'));
return $this->AppContainer->view->render($response, 'habitsoverview', [ return $this->AppContainer->view->render($response, 'habitsoverview', [
'habits' => $this->Database->habits(), 'habits' => $this->Database->habits()->orderBy('name'),
'currentHabits' => $this->HabitsService->GetCurrentHabits(), 'currentHabits' => $this->HabitsService->GetCurrentHabits(),
'nextHabitTimes' => $nextHabitTimes, 'nextHabitTimes' => $nextHabitTimes,
'nextXDays' => $nextXDays, 'nextXDays' => $nextXDays,
@@ -38,14 +38,14 @@ class HabitsController extends BaseController
public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'habittracking', [ return $this->AppContainer->view->render($response, 'habittracking', [
'habits' => $this->Database->habits() 'habits' => $this->Database->habits()->orderBy('name')
]); ]);
} }
public function HabitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function HabitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'habits', [ return $this->AppContainer->view->render($response, 'habits', [
'habits' => $this->Database->habits() 'habits' => $this->Database->habits()->orderBy('name')
]); ]);
} }

View File

@@ -24,7 +24,8 @@ class OpenApiController extends BaseApiController
{ {
$applicationService = new ApplicationService(); $applicationService = new ApplicationService();
$this->OpenApiSpec->info->version = $applicationService->GetInstalledVersion(); $versionInfo = $applicationService->GetInstalledVersion();
$this->OpenApiSpec->info->version = $versionInfo->Version;
$this->OpenApiSpec->info->description = str_replace('PlaceHolderManageApiKeysUrl', $this->AppContainer->UrlManager->ConstructUrl('/manageapikeys'), $this->OpenApiSpec->info->description); $this->OpenApiSpec->info->description = str_replace('PlaceHolderManageApiKeysUrl', $this->AppContainer->UrlManager->ConstructUrl('/manageapikeys'), $this->OpenApiSpec->info->description);
$this->OpenApiSpec->servers[0]->url = $this->AppContainer->UrlManager->ConstructUrl('/api'); $this->OpenApiSpec->servers[0]->url = $this->AppContainer->UrlManager->ConstructUrl('/api');

View File

@@ -22,8 +22,9 @@ class StockController extends BaseController
$countExpiringNextXDays = count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('+5 days')), '<')); $countExpiringNextXDays = count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('+5 days')), '<'));
$countAlreadyExpired = count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('-1 days')), '<')); $countAlreadyExpired = count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('-1 days')), '<'));
return $this->AppContainer->view->render($response, 'stockoverview', [ return $this->AppContainer->view->render($response, 'stockoverview', [
'products' => $this->Database->products(), 'products' => $this->Database->products()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units(), 'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
'locations' => $this->Database->locations()->orderBy('name'),
'currentStock' => $currentStock, 'currentStock' => $currentStock,
'missingProducts' => $this->StockService->GetMissingProducts(), 'missingProducts' => $this->StockService->GetMissingProducts(),
'nextXDays' => $nextXDays, 'nextXDays' => $nextXDays,
@@ -35,21 +36,21 @@ class StockController extends BaseController
public function Purchase(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function Purchase(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'purchase', [ return $this->AppContainer->view->render($response, 'purchase', [
'products' => $this->Database->products() 'products' => $this->Database->products()->orderBy('name')
]); ]);
} }
public function Consume(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function Consume(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'consume', [ return $this->AppContainer->view->render($response, 'consume', [
'products' => $this->Database->products() 'products' => $this->Database->products()->orderBy('name')
]); ]);
} }
public function Inventory(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function Inventory(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'inventory', [ return $this->AppContainer->view->render($response, 'inventory', [
'products' => $this->Database->products() 'products' => $this->Database->products()->orderBy('name')
]); ]);
} }
@@ -57,8 +58,8 @@ class StockController extends BaseController
{ {
return $this->AppContainer->view->render($response, 'shoppinglist', [ return $this->AppContainer->view->render($response, 'shoppinglist', [
'listItems' => $this->Database->shopping_list(), 'listItems' => $this->Database->shopping_list(),
'products' => $this->Database->products(), 'products' => $this->Database->products()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units(), 'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
'missingProducts' => $this->StockService->GetMissingProducts() 'missingProducts' => $this->StockService->GetMissingProducts()
]); ]);
} }
@@ -66,23 +67,23 @@ class StockController extends BaseController
public function ProductsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function ProductsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'products', [ return $this->AppContainer->view->render($response, 'products', [
'products' => $this->Database->products(), 'products' => $this->Database->products()->orderBy('name'),
'locations' => $this->Database->locations(), 'locations' => $this->Database->locations()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units() 'quantityunits' => $this->Database->quantity_units()->orderBy('name')
]); ]);
} }
public function LocationsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function LocationsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'locations', [ return $this->AppContainer->view->render($response, 'locations', [
'locations' => $this->Database->locations() 'locations' => $this->Database->locations()->orderBy('name')
]); ]);
} }
public function QuantityUnitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function QuantityUnitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
return $this->AppContainer->view->render($response, 'quantityunits', [ return $this->AppContainer->view->render($response, 'quantityunits', [
'quantityunits' => $this->Database->quantity_units() 'quantityunits' => $this->Database->quantity_units()->orderBy('name')
]); ]);
} }
@@ -91,8 +92,8 @@ class StockController extends BaseController
if ($args['productId'] == 'new') if ($args['productId'] == 'new')
{ {
return $this->AppContainer->view->render($response, 'productform', [ return $this->AppContainer->view->render($response, 'productform', [
'locations' => $this->Database->locations(), 'locations' => $this->Database->locations()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units(), 'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
'mode' => 'create' 'mode' => 'create'
]); ]);
} }
@@ -100,8 +101,8 @@ class StockController extends BaseController
{ {
return $this->AppContainer->view->render($response, 'productform', [ return $this->AppContainer->view->render($response, 'productform', [
'product' => $this->Database->products($args['productId']), 'product' => $this->Database->products($args['productId']),
'locations' => $this->Database->locations(), 'locations' => $this->Database->locations()->orderBy('name'),
'quantityunits' => $this->Database->quantity_units(), 'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
'mode' => 'edit' 'mode' => 'edit'
]); ]);
} }
@@ -146,7 +147,7 @@ class StockController extends BaseController
if ($args['itemId'] == 'new') if ($args['itemId'] == 'new')
{ {
return $this->AppContainer->view->render($response, 'shoppinglistform', [ return $this->AppContainer->view->render($response, 'shoppinglistform', [
'products' => $this->Database->products(), 'products' => $this->Database->products()->orderBy('name'),
'mode' => 'create' 'mode' => 'create'
]); ]);
} }
@@ -154,7 +155,7 @@ class StockController extends BaseController
{ {
return $this->AppContainer->view->render($response, 'shoppinglistform', [ return $this->AppContainer->view->render($response, 'shoppinglistform', [
'listItem' => $this->Database->shopping_list($args['itemId']), 'listItem' => $this->Database->shopping_list($args['itemId']),
'products' => $this->Database->products(), 'products' => $this->Database->products()->orderBy('name'),
'mode' => 'edit' 'mode' => 'edit'
]); ]);
} }

View File

@@ -18,10 +18,17 @@ class UrlManager
protected $BasePath; protected $BasePath;
public function ConstructUrl($relativePath) public function ConstructUrl($relativePath, $isResource = false)
{
if (DISABLE_URL_REWRITING === false || $isResource === true)
{ {
return rtrim($this->BasePath, '/') . $relativePath; return rtrim($this->BasePath, '/') . $relativePath;
} }
else // Is not a resource and URL rewriting is disabled
{
return rtrim($this->BasePath, '/') . '/index.php' . $relativePath;
}
}
private function GetBaseUrl() private function GetBaseUrl()
{ {

View File

@@ -120,11 +120,16 @@ return array(
'#1 habits are due to be done within the next #2 days' => '#1 Gewohnheiten stehen in den nächsten #2 Tagen an', '#1 habits are due to be done within the next #2 days' => '#1 Gewohnheiten stehen in den nächsten #2 Tagen an',
'#1 habits are overdue to be done' => '#1 Gewohnheiten sind überfällig', '#1 habits are overdue to be done' => '#1 Gewohnheiten sind überfällig',
'Released on' => 'Veröffentlicht am', 'Released on' => 'Veröffentlicht am',
'Consume 1 #1 of #2' => 'Verbrauche 1 #1 #2', 'Consume #3 #1 of #2' => 'Verbrauche #3 #1 #2',
'Added #1 #2 of #3 to stock' => '#1 #2 #3 dem Bestand hinzugefügt', 'Added #1 #2 of #3 to stock' => '#1 #2 #3 dem Bestand hinzugefügt',
'Stock amount of #1 is now #2 #3' => 'Es sind nun #2 #3 #1 im Bestand', 'Stock amount of #1 is now #2 #3' => 'Es sind nun #2 #3 #1 im Bestand',
'Tracked execution of habit #1 on #2' => 'Ausführung von #1 am #2 erfasst', 'Tracked execution of habit #1 on #2' => 'Ausführung von #1 am #2 erfasst',
'Tracked charge cylce of battery #1 on #2' => 'Ladezyklus für Batterie #1 am #2 erfasst', 'Tracked charge cylce of battery #1 on #2' => 'Ladezyklus für Batterie #1 am #2 erfasst',
'Consume all #1 which are currently in stock' => 'Verbrauche den kompletten Bestand von #1',
'All' => 'Alle',
'Track charge cycle of battery #1' => 'Erfasse einen Ladezyklus für Batterie #1',
'Track execution of habit #1' => 'Erfasse eine Ausführung von #1',
'Filter by location' => 'Nach Standort filtern',
//Constants //Constants
'manually' => 'Manuell', 'manually' => 'Manuell',

View File

@@ -26,7 +26,11 @@ if (!Grocy.ActiveNav.isEmpty())
} }
$.timeago.settings.allowFuture = true; $.timeago.settings.allowFuture = true;
RefreshContextualTimeago = function()
{
$('time.timeago').timeago(); $('time.timeago').timeago();
}
RefreshContextualTimeago();
toastr.options = { toastr.options = {
toastClass: 'alert', toastClass: 'alert',

View File

@@ -35,7 +35,7 @@
}); });
$('#batteries-table').DataTable({ $('#batteries-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -1,5 +1,33 @@
$('#batteries-overview-table').DataTable({ $('#batteries-overview-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'desc']], 'order': [[2, 'desc']],
'columnDefs': [
{ 'orderable': false, 'targets': 0 }
],
'language': JSON.parse(L('datatables_localization')) 'language': JSON.parse(L('datatables_localization'))
}); });
$(document).on('click', '.track-charge-cycle-button', function(e)
{
var batteryId = $(e.currentTarget).attr('data-battery-id');
var batteryName = $(e.currentTarget).attr('data-battery-name');
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
Grocy.Api.Get('batteries/track-charge-cycle/' + batteryId + '?tracked_time=' + trackedTime,
function(result)
{
$('#battery-' + batteryId + '-last-tracked-time').parent().effect('highlight', {}, 500);
$('#battery-' + batteryId + '-last-tracked-time').fadeOut(500, function () {
$(this).text(trackedTime).fadeIn(500);
});
$('#battery-' + batteryId + '-last-tracked-time-timeago').attr('datetime', trackedTime);
RefreshContextualTimeago();
toastr.success(L('Tracked charge cylce of battery #1 on #2', batteryName, trackedTime));
},
function(xhr)
{
console.error(xhr);
}
);
});

View File

@@ -35,7 +35,7 @@
}); });
$('#habits-table').DataTable({ $('#habits-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -1,5 +1,33 @@
$('#habits-overview-table').DataTable({ $('#habits-overview-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'desc']], 'order': [[2, 'desc']],
'columnDefs': [
{ 'orderable': false, 'targets': 0 }
],
'language': JSON.parse(L('datatables_localization')) 'language': JSON.parse(L('datatables_localization'))
}); });
$(document).on('click', '.track-habit-button', function(e)
{
var habitId = $(e.currentTarget).attr('data-habit-id');
var habitName = $(e.currentTarget).attr('data-habit-name');
var trackedTime = moment().format('YYYY-MM-DD HH:mm:ss');
Grocy.Api.Get('habits/track-habit-execution/' + habitId + '?tracked_time=' + trackedTime,
function(result)
{
$('#habit-' + habitId + '-last-tracked-time').parent().effect('highlight', {}, 500);
$('#habit-' + habitId + '-last-tracked-time').fadeOut(500, function () {
$(this).text(trackedTime).fadeIn(500);
});
$('#habit-' + habitId + '-last-tracked-time-timeago').attr('datetime', trackedTime);
RefreshContextualTimeago();
toastr.success(L('Tracked execution of habit #1 on #2', habitName, trackedTime));
},
function(xhr)
{
console.error(xhr);
}
);
});

View File

@@ -35,7 +35,7 @@
}); });
$('#locations-table').DataTable({ $('#locations-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -35,7 +35,7 @@
}); });
$('#apikeys-table').DataTable({ $('#apikeys-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[4, 'desc']], 'order': [[4, 'desc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -35,7 +35,7 @@
}); });
$('#products-table').DataTable({ $('#products-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -35,7 +35,7 @@
}); });
$('#quantityunits-table').DataTable({ $('#quantityunits-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -27,7 +27,7 @@ $(document).on('click', '#add-products-below-min-stock-amount', function(e)
}); });
$('#shoppinglist-table').DataTable({ $('#shoppinglist-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[1, 'asc']], 'order': [[1, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 }

View File

@@ -1,10 +1,46 @@
$('#stock-overview-table').DataTable({ var stockOverviewTable = $('#stock-overview-table').DataTable({
'pageLength': 50, 'bPaginate': false,
'order': [[3, 'asc']], 'order': [[3, 'asc']],
'columnDefs': [ 'columnDefs': [
{ 'orderable': false, 'targets': 0 } { 'orderable': false, 'targets': 0 },
{ 'visible': false, 'targets': 4 }
], ],
'language': JSON.parse(L('datatables_localization')) 'language': JSON.parse(L('datatables_localization')),
"dom": '<"filter-by-location">f'
});
$("div.filter-by-location").html('<div class="dataTables_filter"><label>' + L('Filter by location') + ':<select id="location-filter" class="form-control input-sm" style="margin-left: 0.5em;"></label></div>');
$('#stock-overview-table_wrapper').on("DOMSubtreeModified", function()
{
$('#stock-overview-table_wrapper').off("DOMSubtreeModified");
Grocy.Api.Get('get-objects/locations',
function(locations)
{
$('#location-filter').append($('<option></option>').val("all").html(L("All")));
$.each(locations, function(index)
{
var locationName = locations[index].name;
$('#location-filter').append($('<option></option>').val(locationName).html(locationName));
});
},
function(xhr)
{
console.error(xhr);
}
);
$("#location-filter").on("change", function()
{
var value = $(this).val();
if (value === "all")
{
value = "";
}
stockOverviewTable.column(4).search(value).draw();
});
}); });
$(document).on('click', '.product-consume-button', function(e) $(document).on('click', '.product-consume-button', function(e)
@@ -12,22 +48,31 @@ $(document).on('click', '.product-consume-button', function(e)
var productId = $(e.currentTarget).attr('data-product-id'); var productId = $(e.currentTarget).attr('data-product-id');
var productName = $(e.currentTarget).attr('data-product-name'); var productName = $(e.currentTarget).attr('data-product-name');
var productQuName = $(e.currentTarget).attr('data-product-qu-name'); var productQuName = $(e.currentTarget).attr('data-product-qu-name');
var consumeAmount = $(e.currentTarget).attr('data-consume-amount');
Grocy.Api.Get('stock/consume-product/' + productId + '/1', Grocy.Api.Get('stock/consume-product/' + productId + '/' + consumeAmount,
function(result) function(result)
{ {
var oldAmount = parseInt($('#product-' + productId + '-amount').text()); var oldAmount = parseInt($('#product-' + productId + '-amount').text());
var newAmount = oldAmount - 1; var newAmount = oldAmount - consumeAmount;
if (newAmount === 0) if (newAmount === 0)
{ {
$('#product-' + productId + '-row').remove(); $('#product-' + productId + '-row').fadeOut(500, function()
{
$(this).remove();
});
} }
else else
{ {
$('#product-' + productId + '-amount').text(newAmount); $('#product-' + productId + '-amount').parent().effect('highlight', { }, 500);
$('#product-' + productId + '-amount').fadeOut(500, function()
{
$(this).text(newAmount).fadeIn(500);
});
$('#product-' + productId + '-consume-all-button').attr('data-consume-amount', newAmount);
} }
toastr.success(L('Removed #1 #2 of #3 from stock', 1, productQuName, productName)); toastr.success(L('Removed #1 #2 of #3 from stock', consumeAmount, productQuName, productName));
}, },
function(xhr) function(xhr)
{ {

View File

@@ -1,4 +1,4 @@
{ {
"Version": "1.10.0", "Version": "1.12.0",
"ReleaseDate": "2018-05-12" "ReleaseDate": "2018-07-08"
} }

View File

@@ -4,6 +4,10 @@
@section('activeNav', 'batteriesoverview') @section('activeNav', 'batteriesoverview')
@section('viewJsName', 'batteriesoverview') @section('viewJsName', 'batteriesoverview')
@push('pageScripts')
<script src="{{ $U('/bower_components/jquery-ui/jquery-ui.min.js?v=', true) }}{{ $version }}"></script>
@endpush
@section('content') @section('content')
<h1 class="page-header">@yield('title')</h1> <h1 class="page-header">@yield('title')</h1>
@@ -20,6 +24,7 @@
<table id="batteries-overview-table" class="table table-striped"> <table id="batteries-overview-table" class="table table-striped">
<thead> <thead>
<tr> <tr>
<th>#</th>
<th>{{ $L('Battery') }}</th> <th>{{ $L('Battery') }}</th>
<th>{{ $L('Last charged') }}</th> <th>{{ $L('Last charged') }}</th>
<th>{{ $L('Next planned charge cycle') }}</th> <th>{{ $L('Next planned charge cycle') }}</th>
@@ -28,12 +33,19 @@
<tbody> <tbody>
@foreach($current as $curentBatteryEntry) @foreach($current as $curentBatteryEntry)
<tr class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $nextChargeTimes[$curentBatteryEntry->battery_id] < date('Y-m-d H:i:s')) error-bg @endif"> <tr class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $nextChargeTimes[$curentBatteryEntry->battery_id] < date('Y-m-d H:i:s')) error-bg @endif">
<td class="fit-content">
<a class="btn btn-success btn-xs track-charge-cycle-button" href="#" title="{{ $L('Track charge cycle of battery #1', FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name) }}"
data-battery-id="{{ $curentBatteryEntry->battery_id }}"
data-battery-name="{{ FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name }}">
<i class="fa fa-fire"></i>
</a>
</td>
<td> <td>
{{ FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name }} {{ FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name }}
</td> </td>
<td> <td>
{{ $curentBatteryEntry->last_tracked_time }} <span id="battery-{{ $curentBatteryEntry->battery_id }}-last-tracked-time">{{ $curentBatteryEntry->last_tracked_time }}</span>
<time class="timeago timeago-contextual" datetime="{{ $curentBatteryEntry->last_tracked_time }}"></time> <time id="battery-{{ $curentBatteryEntry->battery_id }}-last-tracked-time-timeago" class="timeago timeago-contextual" datetime="{{ $curentBatteryEntry->last_tracked_time }}"></time>
</td> </td>
<td> <td>
@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0) @if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0)

View File

@@ -1,5 +1,5 @@
@push('componentScripts') @push('componentScripts')
<script src="{{ $U('/viewjs/components/batterycard.js') }}?v={{ $version }}"></script> <script src="{{ $U('/viewjs/components/batterycard.js', true) }}?v={{ $version }}"></script>
@endpush @endpush
<div class="main well"> <div class="main well">

View File

@@ -1,5 +1,5 @@
@push('componentScripts') @push('componentScripts')
<script src="{{ $U('/viewjs/components/datepicker.js') }}?v={{ $version }}"></script> <script src="{{ $U('/viewjs/components/datepicker.js', true) }}?v={{ $version }}"></script>
@endpush @endpush
<div class="form-group"> <div class="form-group">

View File

@@ -1,5 +1,5 @@
@push('componentScripts') @push('componentScripts')
<script src="{{ $U('/viewjs/components/datetimepicker.js') }}?v={{ $version }}"></script> <script src="{{ $U('/viewjs/components/datetimepicker.js', true) }}?v={{ $version }}"></script>
@endpush @endpush
<div class="form-group"> <div class="form-group">

View File

@@ -1,5 +1,5 @@
@push('componentScripts') @push('componentScripts')
<script src="{{ $U('/viewjs/components/habitcard.js') }}?v={{ $version }}"></script> <script src="{{ $U('/viewjs/components/habitcard.js', true) }}?v={{ $version }}"></script>
@endpush @endpush
<div class="main well"> <div class="main well">

View File

@@ -1,5 +1,5 @@
@push('componentScripts') @push('componentScripts')
<script src="{{ $U('/viewjs/components/productcard.js') }}?v={{ $version }}"></script> <script src="{{ $U('/viewjs/components/productcard.js', true) }}?v={{ $version }}"></script>
@endpush @endpush
<div class="main well"> <div class="main well">

View File

@@ -4,6 +4,10 @@
@section('activeNav', 'habitsoverview') @section('activeNav', 'habitsoverview')
@section('viewJsName', 'habitsoverview') @section('viewJsName', 'habitsoverview')
@push('pageScripts')
<script src="{{ $U('/bower_components/jquery-ui/jquery-ui.min.js?v=', true) }}{{ $version }}"></script>
@endpush
@section('content') @section('content')
<h1 class="page-header">@yield('title')</h1> <h1 class="page-header">@yield('title')</h1>
@@ -20,6 +24,7 @@
<table id="habits-overview-table" class="table table-striped"> <table id="habits-overview-table" class="table table-striped">
<thead> <thead>
<tr> <tr>
<th>#</th>
<th>{{ $L('Habit') }}</th> <th>{{ $L('Habit') }}</th>
<th>{{ $L('Next estimated tracking') }}</th> <th>{{ $L('Next estimated tracking') }}</th>
<th>{{ $L('Last tracked') }}</th> <th>{{ $L('Last tracked') }}</th>
@@ -28,6 +33,13 @@
<tbody> <tbody>
@foreach($currentHabits as $curentHabitEntry) @foreach($currentHabits as $curentHabitEntry)
<tr class="@if(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $nextHabitTimes[$curentHabitEntry->habit_id] < date('Y-m-d H:i:s')) error-bg @endif"> <tr class="@if(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $nextHabitTimes[$curentHabitEntry->habit_id] < date('Y-m-d H:i:s')) error-bg @endif">
<td class="fit-content">
<a class="btn btn-success btn-xs track-habit-button" href="#" title="{{ $L('Track execution of habit #1', FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name) }}"
data-habit-id="{{ $curentHabitEntry->habit_id }}"
data-habit-name="{{ FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name }}">
<i class="fa fa-play"></i>
</a>
</td>
<td> <td>
{{ FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name }} {{ FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name }}
</td> </td>
@@ -40,8 +52,8 @@
@endif @endif
</td> </td>
<td> <td>
{{ $curentHabitEntry->last_tracked_time }} <span id="habit-{{ $curentHabitEntry->habit_id }}-last-tracked-time">{{ $curentHabitEntry->last_tracked_time }}</span>
<time class="timeago timeago-contextual" datetime="{{ $curentHabitEntry->last_tracked_time }}"></time> <time id="habit-{{ $curentHabitEntry->habit_id }}-last-tracked-time-timeago" class="timeago timeago-contextual" datetime="{{ $curentHabitEntry->last_tracked_time }}"></time>
</td> </td>
</tr> </tr>
@endforeach @endforeach

View File

@@ -9,22 +9,22 @@
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta name="author" content="Bernd Bestel (bernd@berrnd.de)"> <meta name="author" content="Bernd Bestel (bernd@berrnd.de)">
<link rel="icon" type="image/png" sizes="200x200" href="{{ $U('/img/grocy.png?v=') }}{{ $version }}"> <link rel="icon" type="image/png" sizes="200x200" href="{{ $U('/img/grocy.png?v=', true) }}{{ $version }}">
<title>@yield('title') | grocy</title> <title>@yield('title') | grocy</title>
<link href="{{ $U('/bower_components/bootstrap/dist/css/bootstrap.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/bootstrap/dist/css/bootstrap.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/font-awesome/css/font-awesome.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/font-awesome/css/font-awesome.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/bootstrap-combobox/css/bootstrap-combobox.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/bootstrap-combobox/css/bootstrap-combobox.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/datatables.net-responsive-bs/css/responsive.bootstrap.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/datatables.net-responsive-bs/css/responsive.bootstrap.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/toastr/toastr.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/toastr/toastr.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/tagmanager/tagmanager.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/tagmanager/tagmanager.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/bower_components/bootstrap-side-navbar/source/assets/stylesheets/navbar-fixed-side.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/bootstrap-side-navbar/source/assets/stylesheets/navbar-fixed-side.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/components_unmanaged/noto-sans-v6-latin/noto-sans-v6-latin.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/css/grocy.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/css/grocy.css?v=', true) }}{{ $version }}" rel="stylesheet">
@stack('pageStyles') @stack('pageStyles')
<script> <script>
@@ -104,31 +104,31 @@
</div> </div>
</div> </div>
<script src="{{ $U('/bower_components/jquery/dist/jquery.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/jquery/dist/jquery.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/bootstrap/dist/js/bootstrap.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/bootstrap/dist/js/bootstrap.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/bootbox/bootbox.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/bootbox/bootbox.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/jquery.serializeJSON/jquery.serializejson.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/jquery.serializeJSON/jquery.serializejson.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js?v=', true) }}{{ $version }}"></script>
@if(!empty($L('bootstrap_datepicker_locale')))<script src="{{ $U('/bower_components') }}/bootstrap-datepicker/dist/locales/bootstrap-datepicker.{{ $L('bootstrap_datepicker_locale') }}.min.js?v={{ $version }}"></script>@endif @if(!empty($L('bootstrap_datepicker_locale')))<script src="{{ $U('/bower_components', true) }}/bootstrap-datepicker/dist/locales/bootstrap-datepicker.{{ $L('bootstrap_datepicker_locale') }}.min.js?v={{ $version }}"></script>@endif
<script src="{{ $U('/bower_components/moment/min/moment.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/moment/min/moment.min.js?v=', true) }}{{ $version }}"></script>
@if(!empty($L('moment_locale')))<script src="{{ $U('/bower_components') }}/moment/locale/{{ $L('moment_locale') }}.js?v={{ $version }}"></script>@endif @if(!empty($L('moment_locale')))<script src="{{ $U('/bower_components', true) }}/moment/locale/{{ $L('moment_locale') }}.js?v={{ $version }}"></script>@endif
<script src="{{ $U('/bower_components/bootstrap-validator/dist/validator.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/bootstrap-validator/dist/validator.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/bootstrap-combobox/js/bootstrap-combobox.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/bootstrap-combobox/js/bootstrap-combobox.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/datatables.net/js/jquery.dataTables.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/datatables.net/js/jquery.dataTables.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/datatables.net-responsive/js/dataTables.responsive.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/datatables.net-responsive/js/dataTables.responsive.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/datatables.net-responsive-bs/js/responsive.bootstrap.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/datatables.net-responsive-bs/js/responsive.bootstrap.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/jquery-timeago/jquery.timeago.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/jquery-timeago/jquery.timeago.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components') }}/jquery-timeago/locales/jquery.timeago.{{ $L('timeago_locale') }}.js?v={{ $version }}"></script> <script src="{{ $U('/bower_components', true) }}/jquery-timeago/locales/jquery.timeago.{{ $L('timeago_locale') }}.js?v={{ $version }}"></script>
<script src="{{ $U('/bower_components/toastr/toastr.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/toastr/toastr.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/tagmanager/tagmanager.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/tagmanager/tagmanager.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/js/extensions.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/js/extensions.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/js/grocy.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/js/grocy.js?v=', true) }}{{ $version }}"></script>
@stack('pageScripts') @stack('pageScripts')
@stack('componentScripts') @stack('componentScripts')
<script src="{{ $U('/viewjs') }}/@yield('viewJsName').js?v={{ $version }}"></script> <script src="{{ $U('/viewjs', true) }}/@yield('viewJsName').js?v={{ $version }}"></script>
@if(file_exists(__DIR__ . '/../../data/add_before_end_body.html')) @if(file_exists(__DIR__ . '/../../data/add_before_end_body.html'))
@php include __DIR__ . '/../../data/add_before_end_body.html' @endphp @php include __DIR__ . '/../../data/add_before_end_body.html' @endphp

View File

@@ -5,7 +5,7 @@
@section('viewJsName', 'manageapikeys') @section('viewJsName', 'manageapikeys')
@push('pageScripts') @push('pageScripts')
<script src="{{ $U('/bower_components/jquery-ui/jquery-ui.min.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/jquery-ui/jquery-ui.min.js?v=', true) }}{{ $version }}"></script>
@endpush @endpush
@section('content') @section('content')

View File

@@ -9,11 +9,11 @@
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">
<meta name="author" content="Bernd Bestel (bernd@berrnd.de)"> <meta name="author" content="Bernd Bestel (bernd@berrnd.de)">
<link rel="icon" type="image/png" sizes="200x200" href="{{ $U('/img/grocy.png?v=') }}{{ $version }}"> <link rel="icon" type="image/png" sizes="200x200" href="{{ $U('/img/grocy.png?v=', true) }}{{ $version }}">
<title>{{ $L('REST API & data model documentation') }} | grocy</title> <title>{{ $L('REST API & data model documentation') }} | grocy</title>
<link href="{{ $U('/bower_components/swagger-ui/dist/swagger-ui.css?v=') }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/bower_components/swagger-ui/dist/swagger-ui.css?v=', true) }}{{ $version }}" rel="stylesheet">
<script> <script>
var Grocy = { }; var Grocy = { };
@@ -25,9 +25,9 @@
<body> <body>
<div id="swagger-ui"></div> <div id="swagger-ui"></div>
<script src="{{ $U('/bower_components/swagger-ui/dist/swagger-ui-bundle.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/swagger-ui/dist/swagger-ui-bundle.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/bower_components/swagger-ui/dist/swagger-ui-standalone-preset.js?v=') }}{{ $version }}"></script> <script src="{{ $U('/bower_components/swagger-ui/dist/swagger-ui-standalone-preset.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/viewjs') }}/openapiui.js?v={{ $version }}"></script> <script src="{{ $U('/viewjs', true) }}/openapiui.js?v={{ $version }}"></script>
@if(file_exists(__DIR__ . '/../../data/add_before_end_body.html')) @if(file_exists(__DIR__ . '/../../data/add_before_end_body.html'))
@php include __DIR__ . '/../../data/add_before_end_body.html' @endphp @php include __DIR__ . '/../../data/add_before_end_body.html' @endphp

View File

@@ -4,6 +4,10 @@
@section('activeNav', 'stockoverview') @section('activeNav', 'stockoverview')
@section('viewJsName', 'stockoverview') @section('viewJsName', 'stockoverview')
@push('pageScripts')
<script src="{{ $U('/bower_components/jquery-ui/jquery-ui.min.js?v=', true) }}{{ $version }}"></script>
@endpush
@section('content') @section('content')
<h1 class="page-header">{{ $L('Stock overview') }} <span class="text-muted small">{{ $L('#1 products with #2 units in stock', count($currentStock), SumArrayValue($currentStock, 'amount')) }}</span></h1> <h1 class="page-header">{{ $L('Stock overview') }} <span class="text-muted small">{{ $L('#1 products with #2 units in stock', count($currentStock), SumArrayValue($currentStock, 'amount')) }}</span></h1>
@@ -25,17 +29,26 @@
<th>{{ $L('Product') }}</th> <th>{{ $L('Product') }}</th>
<th>{{ $L('Amount') }}</th> <th>{{ $L('Amount') }}</th>
<th>{{ $L('Next best before date') }}</th> <th>{{ $L('Next best before date') }}</th>
<th class="hidden">Hidden location</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@foreach($currentStock as $currentStockEntry) @foreach($currentStock as $currentStockEntry)
<tr id="product-{{ $currentStockEntry->product_id }}-row" class="@if($currentStockEntry->best_before_date < date('Y-m-d', strtotime('-1 days'))) error-bg @elseif($currentStockEntry->best_before_date < date('Y-m-d', strtotime('+5 days'))) warning-bg @elseif (FindObjectInArrayByPropertyValue($missingProducts, 'id', $currentStockEntry->product_id) !== null) info-bg @endif"> <tr id="product-{{ $currentStockEntry->product_id }}-row" class="@if($currentStockEntry->best_before_date < date('Y-m-d', strtotime('-1 days'))) error-bg @elseif($currentStockEntry->best_before_date < date('Y-m-d', strtotime('+5 days'))) warning-bg @elseif (FindObjectInArrayByPropertyValue($missingProducts, 'id', $currentStockEntry->product_id) !== null) info-bg @endif">
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-danger btn-xs product-consume-button" href="#" title="{{ $L('Consume 1 #1 of #2', FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name) }}" <a class="btn btn-success btn-xs product-consume-button" href="#" title="{{ $L('Consume #3 #1 of #2', FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name, FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name, 1) }}"
data-product-id="{{ $currentStockEntry->product_id }}" data-product-id="{{ $currentStockEntry->product_id }}"
data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}" data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}"
data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}"> data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}"
<i class="fa fa-cutlery"></i> data-consume-amount="1">
<i class="fa fa-cutlery"></i> 1
</a>
<a id="product-{{ $currentStockEntry->product_id }}-consume-all-button" class="btn btn-danger btn-xs product-consume-button" href="#" title="{{ $L('Consume all #1 which are currently in stock', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name) }}"
data-product-id="{{ $currentStockEntry->product_id }}"
data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}"
data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}"
data-consume-amount="{{ $currentStockEntry->amount }}">
<i class="fa fa-cutlery"></i> {{ $L('All') }}
</a> </a>
</td> </td>
<td> <td>
@@ -48,6 +61,9 @@
{{ $currentStockEntry->best_before_date }} {{ $currentStockEntry->best_before_date }}
<time class="timeago timeago-contextual" datetime="{{ $currentStockEntry->best_before_date }}"></time> <time class="timeago timeago-contextual" datetime="{{ $currentStockEntry->best_before_date }}"></time>
</td> </td>
<td class="hidden">
{{ FindObjectInArrayByPropertyValue($locations, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->location_id)->name }}
</td>
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>