Import Export Grocery List
And misc improvements
This commit is contained in:
@@ -202,12 +202,16 @@ function migrateLegacyGroceriesIfNeeded(): array {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create catalog row + list line (used by grocery_item_create and meal → grocery).
|
||||
* Append one shopping line using already-loaded catalog and lists (mutates arrays).
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $catalog
|
||||
* @param array{byStore: array<string, array<int, array<string, mixed>>>} $lists
|
||||
* @param array<int, array<string, mixed>> $stores
|
||||
* @return array{ok: bool, item?: array<string, mixed>, error?: string}
|
||||
*/
|
||||
function groceryAppendShoppingLine(
|
||||
function groceryAppendShoppingLineIntoBuffers(
|
||||
array &$catalog,
|
||||
array &$lists,
|
||||
array $stores,
|
||||
string $storeId,
|
||||
string $name,
|
||||
@@ -234,7 +238,6 @@ function groceryAppendShoppingLine(
|
||||
$price = trim($price);
|
||||
$image = trim($image);
|
||||
|
||||
$catalog = normalizeCatalogList(readJsonFile('grocery_catalog.json'));
|
||||
$dedupeKey = groceryCatalogDedupeKey($storeId, $name, $size);
|
||||
$catalogId = null;
|
||||
foreach ($catalog as $i => $c) {
|
||||
@@ -296,12 +299,58 @@ function groceryAppendShoppingLine(
|
||||
$line['mealTitle'] = $mealTitleMeta;
|
||||
}
|
||||
|
||||
$lists = normalizeGroceryLists(readJsonFile('grocery_lists.json'));
|
||||
if (!isset($lists['byStore'][$storeId])) {
|
||||
$lists['byStore'][$storeId] = [];
|
||||
}
|
||||
$lists['byStore'][$storeId][] = $line;
|
||||
|
||||
return ['ok' => true, 'item' => $line];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create catalog row + list line (used by grocery_item_create and meal → grocery).
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $stores
|
||||
* @return array{ok: bool, item?: array<string, mixed>, error?: string}
|
||||
*/
|
||||
function groceryAppendShoppingLine(
|
||||
array $stores,
|
||||
string $storeId,
|
||||
string $name,
|
||||
string $description = '',
|
||||
string $size = '',
|
||||
string $quantity = '1',
|
||||
string $price = '',
|
||||
string $image = '',
|
||||
string $source = 'manual',
|
||||
int $recurringIntervalDays = 0,
|
||||
?string $mealId = null,
|
||||
?string $mealTitleMeta = null
|
||||
): array {
|
||||
$catalog = normalizeCatalogList(readJsonFile('grocery_catalog.json'));
|
||||
$lists = normalizeGroceryLists(readJsonFile('grocery_lists.json'));
|
||||
|
||||
$res = groceryAppendShoppingLineIntoBuffers(
|
||||
$catalog,
|
||||
$lists,
|
||||
$stores,
|
||||
$storeId,
|
||||
$name,
|
||||
$description,
|
||||
$size,
|
||||
$quantity,
|
||||
$price,
|
||||
$image,
|
||||
$source,
|
||||
$recurringIntervalDays,
|
||||
$mealId,
|
||||
$mealTitleMeta
|
||||
);
|
||||
|
||||
if (!$res['ok']) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
if (!writeJsonFile('grocery_catalog.json', $catalog)) {
|
||||
return ['ok' => false, 'error' => 'Failed to save catalog'];
|
||||
}
|
||||
@@ -309,7 +358,79 @@ function groceryAppendShoppingLine(
|
||||
return ['ok' => false, 'error' => 'Failed to save grocery list'];
|
||||
}
|
||||
|
||||
return ['ok' => true, 'item' => $line];
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append several meal shopping lines in one disk transaction (catalog + lists).
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $stores
|
||||
* @param list<array{name?:mixed, storeId?:mixed, description?:mixed, size?:mixed, quantity?:mixed, price?:mixed, image?:mixed}> $itemRows
|
||||
* @return int number of lines successfully added
|
||||
*/
|
||||
function groceryAppendMealItemRowsBatch(
|
||||
array $stores,
|
||||
array $itemRows,
|
||||
string $mealId,
|
||||
string $mealTitle
|
||||
): int {
|
||||
if (count($itemRows) === 0) {
|
||||
return 0;
|
||||
}
|
||||
$defaultStore = groceryFirstStoreId($stores);
|
||||
if ($defaultStore === '') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$catalog = normalizeCatalogList(readJsonFile('grocery_catalog.json'));
|
||||
$lists = normalizeGroceryLists(readJsonFile('grocery_lists.json'));
|
||||
$added = 0;
|
||||
|
||||
foreach ($itemRows as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$name = trim((string) ($row['name'] ?? ''));
|
||||
if ($name === '') {
|
||||
continue;
|
||||
}
|
||||
$sid = trim((string) ($row['storeId'] ?? ''));
|
||||
if ($sid === '' || findStoreById($stores, $sid) === null) {
|
||||
$sid = $defaultStore;
|
||||
}
|
||||
$res = groceryAppendShoppingLineIntoBuffers(
|
||||
$catalog,
|
||||
$lists,
|
||||
$stores,
|
||||
$sid,
|
||||
$name,
|
||||
trim((string) ($row['description'] ?? '')),
|
||||
trim((string) ($row['size'] ?? '')),
|
||||
trim((string) ($row['quantity'] ?? '1')) ?: '1',
|
||||
trim((string) ($row['price'] ?? '')),
|
||||
trim((string) ($row['image'] ?? '')),
|
||||
'meal_plan',
|
||||
0,
|
||||
$mealId !== '' ? $mealId : null,
|
||||
$mealTitle !== '' ? $mealTitle : null
|
||||
);
|
||||
if ($res['ok']) {
|
||||
$added++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($added === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!writeJsonFile('grocery_catalog.json', $catalog)) {
|
||||
return 0;
|
||||
}
|
||||
if (!writeJsonFile('grocery_lists.json', $lists)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $added;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user