Squashed commit

Always execute migration 9999 (can be used to fix things manually)
Optimized meal plan navigation / date range filtering
Prepared next release
Pulled translations from Transifex
Various code optimizations
This commit is contained in:
Bernd Bestel
2021-07-16 17:32:08 +02:00
parent 2d1d5d46f6
commit edfa404ed6
58 changed files with 312 additions and 513 deletions

View File

@@ -9,7 +9,6 @@ class ApplicationService extends BaseService
public function GetChangelog()
{
$changelogItems = [];
foreach (glob(__DIR__ . '/../changelog/*.md') as $file)
{
$fileName = basename($file);

View File

@@ -6,14 +6,9 @@ class BaseService
{
private static $instances = [];
public function __construct()
{
}
public static function getInstance()
{
$className = get_called_class();
if (!isset(self::$instances[$className]))
{
self::$instances[$className] = new $className();

View File

@@ -6,6 +6,13 @@ use Grocy\Helpers\UrlManager;
class CalendarService extends BaseService
{
public function __construct()
{
$this->UrlManager = new UrlManager(GROCY_BASE_URL);
}
private $UrlManager;
public function GetEvents()
{
$stockEvents = [];
@@ -148,10 +155,4 @@ class CalendarService extends BaseService
return array_merge($stockEvents, $taskEvents, $choreEvents, $batteryEvents, $mealPlanRecipeEvents, $mealPlanNotesEvents, $mealPlanProductEvents);
}
public function __construct()
{
parent::__construct();
$this->UrlManager = new UrlManager(GROCY_BASE_URL);
}
}

View File

@@ -38,7 +38,6 @@ class ChoresService extends BaseService
$users = $this->getUsersService()->GetUsersAsDto();
$assignedUsers = [];
foreach ($users as $user)
{
if (in_array($user->id, explode(',', $chore->assignment_config)))
@@ -210,11 +209,6 @@ class ChoresService extends BaseService
]);
}
public function __construct()
{
parent::__construct();
}
private function ChoreExists($choreId)
{
$choreRow = $this->getDatabase()->chores()->where('id = :1', $choreId)->fetch();

View File

@@ -4,6 +4,9 @@ namespace Grocy\Services;
class DatabaseMigrationService extends BaseService
{
// This migration will be always execute, can be used to fix things manually
const EMERGENCY_MIGRATION_ID = 9999;
public function MigrateDatabase()
{
$this->getDatabaseService()->ExecuteDbStatement("CREATE TABLE IF NOT EXISTS migrations (migration INTEGER NOT NULL PRIMARY KEY UNIQUE, execution_time_timestamp DATETIME DEFAULT (datetime('now', 'localtime')))");
@@ -36,10 +39,14 @@ class DatabaseMigrationService extends BaseService
{
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
if (intval($rowCount) === 0)
if (intval($rowCount) === 0 || $migrationId == self::EMERGENCY_MIGRATION_ID)
{
include $phpFile;
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
if ($migrationId != self::EMERGENCY_MIGRATION_ID)
{
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
}
}
}
@@ -47,14 +54,18 @@ class DatabaseMigrationService extends BaseService
{
$rowCount = $this->getDatabaseService()->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = ' . $migrationId)->fetchColumn();
if (intval($rowCount) === 0)
if (intval($rowCount) === 0 || $migrationId == self::EMERGENCY_MIGRATION_ID)
{
$this->getDatabaseService()->GetDbConnectionRaw()->beginTransaction();
try
{
$this->getDatabaseService()->ExecuteDbStatement($sql);
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
if ($migrationId != self::EMERGENCY_MIGRATION_ID)
{
$this->getDatabaseService()->ExecuteDbStatement('INSERT INTO migrations (migration) VALUES (' . $migrationId . ')');
}
}
catch (Exception $ex)
{

View File

@@ -4,6 +4,11 @@ namespace Grocy\Services;
class DemoDataGeneratorService extends BaseService
{
public function __construct()
{
$this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
}
protected $LocalizationService;
private $LastSupermarketId = 1;
@@ -343,12 +348,6 @@ class DemoDataGeneratorService extends BaseService
}
}
public function __construct()
{
parent::__construct();
$this->LocalizationService = new LocalizationService(GROCY_DEFAULT_LOCALE);
}
private function DownloadFileIfNotAlreadyExists($sourceUrl, $destinationPath)
{
if (!file_exists($destinationPath))

View File

@@ -8,6 +8,30 @@ class FilesService extends BaseService
{
const FILE_SERVE_TYPE_PICTURE = 'picture';
public function __construct()
{
$this->StoragePath = GROCY_DATAPATH . '/storage';
if (!file_exists($this->StoragePath))
{
mkdir($this->StoragePath);
}
if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
{
$dbSuffix = GROCY_DEFAULT_LOCALE;
if (defined('GROCY_DEMO_DB_SUFFIX'))
{
$dbSuffix = GROCY_DEMO_DB_SUFFIX;
}
$this->StoragePath = $this->StoragePath . '/' . $dbSuffix;
if (!file_exists($this->StoragePath))
{
mkdir($this->StoragePath);
}
}
}
private $StoragePath;
public function DownscaleImage($group, $fileName, $bestFitHeight = null, $bestFitWidth = null)
@@ -58,8 +82,9 @@ class FilesService extends BaseService
$fileNameWithoutExtension = pathinfo($filePath, PATHINFO_FILENAME);
$fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
// Then the file is an image
if (getimagesize($filePath) !== false)
{ // Then the file is an image
{
// Also delete all corresponding "__downscaledto" files when deleting an image
$groupFolderPath = $this->StoragePath . '/' . $group;
$files = scandir($groupFolderPath);
@@ -87,32 +112,4 @@ class FilesService extends BaseService
return $groupFolderPath . '/' . $fileName;
}
public function __construct()
{
parent::__construct();
$this->StoragePath = GROCY_DATAPATH . '/storage';
if (!file_exists($this->StoragePath))
{
mkdir($this->StoragePath);
}
if (GROCY_MODE === 'demo' || GROCY_MODE === 'prerelease')
{
$dbSuffix = GROCY_DEFAULT_LOCALE;
if (defined('GROCY_DEMO_DB_SUFFIX'))
{
$dbSuffix = GROCY_DEMO_DB_SUFFIX;
}
$this->StoragePath = $this->StoragePath . '/' . $dbSuffix;
if (!file_exists($this->StoragePath))
{
mkdir($this->StoragePath);
}
}
}
}

View File

@@ -8,6 +8,13 @@ use Gettext\Translator;
class LocalizationService
{
public function __construct(string $culture)
{
$this->Culture = $culture;
$this->LoadLocalizations($culture);
}
protected $Po;
protected $PoUserStrings;
@@ -62,13 +69,6 @@ class LocalizationService
return $this->Po->toJsonString();
}
public function __construct(string $culture)
{
$this->Culture = $culture;
$this->LoadLocalizations($culture);
}
public function __n($number, $singularForm, $pluralForm)
{
$this->CheckAndAddMissingTranslationToPot($singularForm);

View File

@@ -10,6 +10,39 @@ use Mike42\Escpos\Printer;
class PrintService extends BaseService
{
/**
* @param bool $printHeader Printing of Grocy logo
* @param string[] $lines Items to print
* @return string[] Returns array with result OK if no exception
* @throws Exception If unable to print, an exception is thrown
*/
public function printShoppingList(bool $printHeader, array $lines): array
{
$printer = self::getPrinterHandle();
if ($printer === false)
{
throw new Exception('Unable to connect to printer');
}
if ($printHeader)
{
self::printHeader($printer);
}
foreach ($lines as $line)
{
$printer->text($line);
$printer->feed();
}
$printer->feed(3);
$printer->cut();
$printer->close();
return [
'result' => 'OK'
];
}
/**
* Initialises the printer
* @return Printer Printer handle
@@ -50,37 +83,4 @@ class PrintService extends BaseService
$printer->selectPrintMode();
$printer->feed(2);
}
/**
* @param bool $printHeader Printing of Grocy logo
* @param string[] $lines Items to print
* @return string[] Returns array with result OK if no exception
* @throws Exception If unable to print, an exception is thrown
*/
public function printShoppingList(bool $printHeader, array $lines): array
{
$printer = self::getPrinterHandle();
if ($printer === false)
{
throw new Exception('Unable to connect to printer');
}
if ($printHeader)
{
self::printHeader($printer);
}
foreach ($lines as $line)
{
$printer->text($line);
$printer->feed();
}
$printer->feed(3);
$printer->cut();
$printer->close();
return [
'result' => 'OK'
];
}
}

View File

@@ -63,8 +63,8 @@ class RecipesService extends BaseService
}
$transactionId = uniqid();
$recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
$recipePositions = $this->getDatabase()->recipes_pos_resolved()->where('recipe_id', $recipeId)->fetchAll();
foreach ($recipePositions as $recipePosition)
{
if ($recipePosition->only_check_single_unit_in_stock == 0)
@@ -129,11 +129,6 @@ class RecipesService extends BaseService
return $lastInsertId;
}
public function __construct()
{
parent::__construct();
}
private function RecipeExists($recipeId)
{
$recipeRow = $this->getDataBase()->recipes()->where('id = :1', $recipeId)->fetch();

View File

@@ -12,7 +12,6 @@ class SessionService extends BaseService
public function CreateSession($userId, $stayLoggedInPermanently = false)
{
$newSessionKey = $this->GenerateSessionKey();
$expires = date('Y-m-d H:i:s', intval(time() + 2592000));
// Default is that sessions expire in 30 days
@@ -39,7 +38,6 @@ class SessionService extends BaseService
public function GetUserBySessionKey($sessionKey)
{
$sessionRow = $this->getDatabase()->sessions()->where('session_key', $sessionKey)->fetch();
if ($sessionRow !== null)
{
return $this->getDatabase()->users($sessionRow->user_id);
@@ -60,7 +58,6 @@ class SessionService extends BaseService
else
{
$sessionRow = $this->getDatabase()->sessions()->where('session_key = :1 AND expires > :2', $sessionKey, date('Y-m-d H:i:s', time()))->fetch();
if ($sessionRow !== null)
{
// This should not change the database file modification time as this is used

View File

@@ -33,7 +33,6 @@ class StockService extends BaseService
}
$missingProducts = $this->GetMissingProducts();
foreach ($missingProducts as $missingProduct)
{
$product = $this->getDatabase()->products()->where('id', $missingProduct->id)->fetch();
@@ -42,7 +41,8 @@ class StockService extends BaseService
$alreadyExistingEntry = $this->getDatabase()->shopping_list()->where('product_id', $missingProduct->id)->fetch();
if ($alreadyExistingEntry)
{ // Update
{
// Update
if ($alreadyExistingEntry->amount < $amountToAdd)
{
$alreadyExistingEntry->update([
@@ -52,7 +52,8 @@ class StockService extends BaseService
}
}
else
{ // Insert
{
// Insert
$shoppinglistRow = $this->getDatabase()->shopping_list()->createRow([
'product_id' => $missingProduct->id,
'amount' => $amountToAdd,
@@ -197,7 +198,8 @@ class StockService extends BaseService
{
$reps = 1;
if ($runWebhook == 2)
{ // 2 == run $amount times
{
// 2 == run $amount times
$reps = intval(floor($amount));
}
@@ -428,7 +430,6 @@ class StockService extends BaseService
public function EditStockEntry(int $stockRowId, float $amount, $bestBeforeDate, $locationId, $shoppingLocationId, $price, $open, $purchasedDate)
{
$stockRow = $this->getDatabase()->stock()->where('id = :1', $stockRowId)->fetch();
if ($stockRow === null)
{
throw new \Exception('Stock does not exist');
@@ -455,7 +456,6 @@ class StockService extends BaseService
$logOldRowForStockUpdate->save();
$openedDate = $stockRow->opened_date;
if (boolval($open) && $openedDate == null)
{
$openedDate = date('Y-m-d');
@@ -505,7 +505,8 @@ class StockService extends BaseService
$pluginOutput = $plugin->Lookup($barcode);
if ($pluginOutput !== null)
{ // Lookup was successful
{
// Lookup was successful
if ($addFoundProduct === true)
{
// Add product to database and include new product id in output
@@ -522,7 +523,6 @@ class StockService extends BaseService
public function GetCurrentStock($includeNotInStockButMissingProducts = false)
{
$sql = 'SELECT * FROM stock_current';
if ($includeNotInStockButMissingProducts)
{
$missingProductsView = 'stock_missing_products_including_opened';
@@ -538,7 +538,6 @@ class StockService extends BaseService
$currentStockMapped = $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_GROUP | \PDO::FETCH_OBJ);
$relevantProducts = $this->getDatabase()->products()->where('id IN (SELECT product_id FROM (' . $sql . ') x)');
foreach ($relevantProducts as $product)
{
$currentStockMapped[$product->id][0]->product_id = $product->id;
@@ -614,7 +613,6 @@ class StockService extends BaseService
}
$stockCurrentRow = FindObjectinArrayByPropertyValue($this->GetCurrentStock(), 'product_id', $productId);
if ($stockCurrentRow == null)
{
$stockCurrentRow = new \stdClass();
@@ -665,7 +663,6 @@ class StockService extends BaseService
{
$consumeCount = 1;
}
$spoilRate = ($consumeCountSpoiled * 100.0) / $consumeCount;
return [
@@ -704,7 +701,6 @@ class StockService extends BaseService
}
$potentialProduct = $this->getDatabase()->product_barcodes()->where('barcode = :1', $barcode)->fetch();
if ($potentialProduct === null)
{
throw new \Exception("No product with barcode $barcode found");
@@ -722,8 +718,8 @@ class StockService extends BaseService
$returnData = [];
$shoppingLocations = $this->getDatabase()->shopping_locations();
$rows = $this->getDatabase()->product_price_history()->where('product_id = :1', $productId)->orderBy('purchased_date', 'DESC');
$rows = $this->getDatabase()->product_price_history()->where('product_id = :1', $productId)->orderBy('purchased_date', 'DESC');
foreach ($rows as $row)
{
$returnData[] = [
@@ -998,6 +994,7 @@ class StockService extends BaseService
{
$decimals = intval($this->getUsersService()->GetUserSetting(GROCY_USER_ID, 'stock_decimal_places_amounts'));
$newAmount = $productRow->amount - $amount;
if ($newAmount < floatval('0.' . str_repeat('0', $decimals - ($decimals <= 0 ? 0 : 1)) . '1'))
{
$productRow->delete();
@@ -1032,13 +1029,16 @@ class StockService extends BaseService
{
$product = $this->getDatabase()->products()->where('id = :1', $row->product_id)->fetch();
$conversion = $this->getDatabase()->quantity_unit_conversions_resolved()->where('product_id = :1 AND from_qu_id = :2 AND to_qu_id = :3', $product->id, $product->qu_id_stock, $row->qu_id)->fetch();
$factor = 1.0;
if ($conversion != null)
{
$factor = floatval($conversion->factor);
}
$amount = round($row->amount * $factor);
$note = '';
if (GROCY_TPRINTER_PRINT_NOTES)
{
if ($row->note != '')
@@ -1047,6 +1047,7 @@ class StockService extends BaseService
}
}
}
if (GROCY_TPRINTER_PRINT_QUANTITY_NAME && $isValidProduct)
{
$quantityname = $row->qu_name;
@@ -1054,6 +1055,7 @@ class StockService extends BaseService
{
$quantityname = $row->qu_name_plural;
}
array_push($result_quantity, $amount . ' ' . $quantityname);
array_push($result_product, $row->product_name . $note);
}
@@ -1071,6 +1073,7 @@ class StockService extends BaseService
}
}
}
//Add padding to look nicer
$maxlength = 1;
foreach ($result_quantity as $quantity)
@@ -1080,6 +1083,7 @@ class StockService extends BaseService
$maxlength = strlen($quantity);
}
}
$result = [];
$length = count($result_quantity);
for ($i = 0; $i < $length; $i++)
@@ -1087,6 +1091,7 @@ class StockService extends BaseService
$quantity = str_pad($result_quantity[$i], $maxlength);
array_push($result, $quantity . ' ' . $result_product[$i]);
}
return $result;
}
@@ -1222,7 +1227,8 @@ class StockService extends BaseService
$amount -= $stockEntry->amount;
}
else
{ // Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
{
// Stock entry amount is > than needed amount -> split the stock entry resp. update the amount
$restStockAmount = $stockEntry->amount - $amount;
$logRowForLocationFrom = $this->getDatabase()->stock_log()->createRow([

View File

@@ -149,11 +149,6 @@ class UserfieldsService extends BaseService
}
}
public function __construct()
{
parent::__construct();
}
protected function getOpenApispec()
{
if ($this->OpenApiSpec == null)

View File

@@ -97,7 +97,6 @@ class UsersService extends BaseService
public function SetUserSetting($userId, $settingKey, $settingValue)
{
$settingRow = $this->getDatabase()->user_settings()->where('user_id = :1 AND key = :2', $userId, $settingKey)->fetch();
if ($settingRow !== null)
{
$settingRow->update([