mirror of
https://github.com/grocy/grocy.git
synced 2026-03-28 07:39:25 +01:00
Merge pull request #1 from nishizhen/feature/china-localization-and-danshari-report
feat: Adapt Grocy for Chinese Market with New Report and Localization
This commit is contained in:
commit
b90b0c6332
7
TODO.md
Normal file
7
TODO.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Todo List
|
||||
|
||||
## Barcode Lookup API for China
|
||||
|
||||
- **Task:** Find and integrate a barcode lookup service that is more suitable for the Chinese market.
|
||||
- **Status:** Paused. Research into available APIs has not yet yielded a suitable, publicly available service. The initial candidate from Yonyou Cloud was found to be discontinued.
|
||||
- **Next Steps:** Continue researching and evaluating potential barcode lookup APIs for Chinese products. Possible search terms: "商品条码查询API", "ean aPI china", etc. Look into API marketplaces like Aliyun API market or others.
|
||||
|
|
@ -102,4 +102,24 @@ class StockReportsController extends BaseController
|
|||
'groupBy' => $groupBy
|
||||
]);
|
||||
}
|
||||
|
||||
public function LastUsed(Request $request, Response $response, array $args)
|
||||
{
|
||||
$sql = "
|
||||
SELECT
|
||||
p.id,
|
||||
p.name,
|
||||
sc.amount,
|
||||
MAX(sl.used_date) as last_used
|
||||
FROM products p
|
||||
JOIN stock_current sc ON p.id = sc.product_id
|
||||
LEFT JOIN stock_log sl ON p.id = sl.product_id AND sl.transaction_type = 'consume'
|
||||
GROUP BY p.id, p.name, sc.amount
|
||||
ORDER BY last_used IS NULL DESC, last_used ASC
|
||||
";
|
||||
|
||||
return $this->renderPage($response, 'stockreportlastused', [
|
||||
'products' => $this->getDatabaseService()->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ msgid "Invalid credentials, please try again"
|
|||
msgstr "用户名或者密码错误,请重试"
|
||||
|
||||
msgid "Are you sure you want to delete battery \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除电池“%s”吗?"
|
||||
|
||||
msgid "Yes"
|
||||
msgstr "是"
|
||||
|
|
@ -288,7 +288,7 @@ msgid "No"
|
|||
msgstr "否"
|
||||
|
||||
msgid "Are you sure you want to delete chore \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除家务“%s”吗?"
|
||||
|
||||
msgid "\"%s\" could not be resolved to a product, how do you want to proceed?"
|
||||
msgstr "没有找到对应的产品“%s”,您想要执行哪一项操作?"
|
||||
|
|
@ -309,16 +309,16 @@ msgid "Add as new product and prefill barcode"
|
|||
msgstr "作为新产品添加并录入条码"
|
||||
|
||||
msgid "Are you sure you want to delete quantity unit \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除数量单位“%s”吗?"
|
||||
|
||||
msgid "Are you sure you want to delete product \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除产品“%s”吗?"
|
||||
|
||||
msgid "Are you sure you want to delete location \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除位置“%s”吗?"
|
||||
|
||||
msgid "Are you sure you want to delete store \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除商店“%s”吗?"
|
||||
|
||||
msgid "Manage API keys"
|
||||
msgstr "管理API 密钥"
|
||||
|
|
@ -432,13 +432,13 @@ msgid "Edit recipe ingredient"
|
|||
msgstr "编辑食材"
|
||||
|
||||
msgid "Are you sure you want to delete recipe \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除菜谱“%s”吗?"
|
||||
|
||||
msgid "Are you sure you want to delete recipe ingredient \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除菜谱配料“%s”吗?"
|
||||
|
||||
msgid "Are you sure you want to empty shopping list \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要清空购物清单“%s”吗?"
|
||||
|
||||
msgid "Clear list"
|
||||
msgstr "清空列表"
|
||||
|
|
@ -482,7 +482,7 @@ msgstr "将缺少的数量加入购物清单"
|
|||
msgid ""
|
||||
"Are you sure you want to put all missing ingredients for recipe \"%s\" on "
|
||||
"the shopping list?"
|
||||
msgstr ""
|
||||
msgstr "您确定要将菜谱“%s”中所有缺少的配料添加到购物清单吗?"
|
||||
|
||||
msgid "Manage users"
|
||||
msgstr "管理用户"
|
||||
|
|
@ -494,7 +494,7 @@ msgid "Users"
|
|||
msgstr "用户"
|
||||
|
||||
msgid "Are you sure you want to delete user \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除用户“%s”吗?"
|
||||
|
||||
msgid "Create user"
|
||||
msgstr "新建用户"
|
||||
|
|
@ -586,10 +586,10 @@ msgid ""
|
|||
"Are you sure you want to consume all ingredients needed by recipe \"%s\" "
|
||||
"(ingredients marked with \"only check if any amount is in stock\" will be "
|
||||
"ignored)?"
|
||||
msgstr ""
|
||||
msgstr "您确定要消耗菜谱“%s”所需的所有配料吗(标记为“仅检查是否有库存”的配料将被忽略)?"
|
||||
|
||||
msgid "Removed all in stock ingredients needed by recipe \"%s\" from stock"
|
||||
msgstr ""
|
||||
msgstr "已从库存中移除菜谱“%s”所需的所有库存配料"
|
||||
|
||||
msgid "Consume all ingredients needed by this recipe"
|
||||
msgstr "消耗此菜谱所需的全部食材"
|
||||
|
|
@ -640,7 +640,7 @@ msgid "Edit task"
|
|||
msgstr "编辑任务"
|
||||
|
||||
msgid "Are you sure you want to delete task \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除任务“%s”吗?"
|
||||
|
||||
msgid "%s task is due to be done"
|
||||
msgid_plural "%s tasks are due to be done"
|
||||
|
|
@ -672,7 +672,7 @@ msgid "Product group"
|
|||
msgstr "产品组"
|
||||
|
||||
msgid "Are you sure you want to delete product group \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除产品组“%s”吗?"
|
||||
|
||||
msgid "Stay logged in permanently"
|
||||
msgstr "保持登陆状态"
|
||||
|
|
@ -995,7 +995,7 @@ msgid "Create shopping list"
|
|||
msgstr "新建购物清单"
|
||||
|
||||
msgid "Are you sure you want to delete shopping list \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除购物清单“%s”吗?"
|
||||
|
||||
msgid "Average shelf life"
|
||||
msgstr "平均寿命"
|
||||
|
|
@ -1581,7 +1581,7 @@ msgid "Frozen"
|
|||
msgstr "冷冻"
|
||||
|
||||
msgid "Are you sure you want to delete userentity \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除用户实体“%s”吗?"
|
||||
|
||||
msgid "Shopping list settings"
|
||||
msgstr "购物清单设置"
|
||||
|
|
@ -1677,7 +1677,7 @@ msgid ""
|
|||
"Based on the prices of the default consume rule (Opened first, then first "
|
||||
"due first, then first in first out) for in stock ingredients and on the last"
|
||||
" price for missing ones"
|
||||
msgstr ""
|
||||
msgstr "根据默认消耗规则(先开封,然后先到期,然后先进先出)的库存配料价格和缺少配料的最后价格计算"
|
||||
|
||||
msgid "Clear filter"
|
||||
msgstr "清除筛选"
|
||||
|
|
@ -1839,7 +1839,7 @@ msgid ""
|
|||
msgstr "当采购产品的到期日期早于库存产品的下次到期日期时显示警告"
|
||||
|
||||
msgid "This is due earlier than already in stock items"
|
||||
msgstr ""
|
||||
msgstr "此商品比库存中的商品更早到期"
|
||||
|
||||
msgid ""
|
||||
"When enabled, after changing/scanning a product and if all fields could be "
|
||||
|
|
@ -1864,7 +1864,7 @@ msgid "Copy"
|
|||
msgstr "复制"
|
||||
|
||||
msgid "Are you sure you want to remove this barcode?"
|
||||
msgstr ""
|
||||
msgstr "您确定要移除此条形码吗?"
|
||||
|
||||
msgid "Due date type"
|
||||
msgstr "到期日期类型"
|
||||
|
|
@ -2029,7 +2029,7 @@ msgid "Reset"
|
|||
msgstr "重置"
|
||||
|
||||
msgid "Are you sure you want to reset the table options?"
|
||||
msgstr ""
|
||||
msgstr "您确定要重置表格选项吗?"
|
||||
|
||||
msgid "Hide/view columns"
|
||||
msgstr "显示/隐藏 列"
|
||||
|
|
@ -2093,7 +2093,7 @@ msgid ""
|
|||
"The stock overview page lists all products which are currently in stock or "
|
||||
"below their min. stock amount - enable this to hide this product there "
|
||||
"always"
|
||||
msgstr ""
|
||||
msgstr "库存概览页面列出了所有当前有货或低于最低库存量的产品 - 启用此项可始终在此处隐藏该产品"
|
||||
|
||||
msgid "Print options"
|
||||
msgstr "打印选项"
|
||||
|
|
@ -2164,7 +2164,7 @@ msgid "Only done items"
|
|||
msgstr "仅完成项目"
|
||||
|
||||
msgid "Show only in stock products"
|
||||
msgstr ""
|
||||
msgstr "仅显示有库存的产品"
|
||||
|
||||
msgid "Product description"
|
||||
msgstr "产品描述"
|
||||
|
|
@ -2186,7 +2186,7 @@ msgid "When enabled, then this field must be filled on the destination form"
|
|||
msgstr "启用后,必须在目标表单上填写此字段"
|
||||
|
||||
msgid "In stock products"
|
||||
msgstr ""
|
||||
msgstr "库存产品"
|
||||
|
||||
msgid "Timestamp"
|
||||
msgstr "时间戳"
|
||||
|
|
@ -2265,13 +2265,13 @@ msgid "Edit meal plan section"
|
|||
msgstr "编辑饮食计划时段"
|
||||
|
||||
msgid "Are you sure you want to delete meal plan section \"%s\"?"
|
||||
msgstr ""
|
||||
msgstr "您确定要删除用餐计划部分“%s”吗?"
|
||||
|
||||
msgid "Section"
|
||||
msgstr "时段"
|
||||
|
||||
msgid "Are you sure you want to empty the shopping list?"
|
||||
msgstr ""
|
||||
msgstr "您确定要清空购物清单吗?"
|
||||
|
||||
msgid "This is the default which will be prefilled on purchase"
|
||||
msgstr "在采购页面预先填入的默认值"
|
||||
|
|
@ -2537,7 +2537,7 @@ msgid "Stock report"
|
|||
msgstr "库存报表"
|
||||
|
||||
msgid "Out of stock products"
|
||||
msgstr ""
|
||||
msgstr "缺货产品"
|
||||
|
||||
msgid "Quantity unit for prices"
|
||||
msgstr "价格数量单位"
|
||||
|
|
@ -2552,7 +2552,7 @@ msgid_plural "This means %1$s labels will be printed"
|
|||
msgstr[0] "%1$s个标签将被打印"
|
||||
|
||||
msgid "External barcode lookup"
|
||||
msgstr ""
|
||||
msgstr "外部条码查询"
|
||||
|
||||
msgid "Error while executing the barcode lookup plugin"
|
||||
msgstr "运行条码查询插件时出错"
|
||||
|
|
@ -2564,48 +2564,60 @@ msgid "Configure colors"
|
|||
msgstr "配置颜色"
|
||||
|
||||
msgid "Swap track next schedule / track now buttons"
|
||||
msgstr ""
|
||||
msgstr "交换“跟踪下一个计划”/“立即跟踪”按钮"
|
||||
|
||||
msgid "Scheduled tracking time"
|
||||
msgstr ""
|
||||
msgstr "计划跟踪时间"
|
||||
|
||||
msgid "Time of tracking"
|
||||
msgstr ""
|
||||
msgstr "跟踪时间"
|
||||
|
||||
msgid "Show all out of stock products"
|
||||
msgstr ""
|
||||
msgstr "显示所有缺货产品"
|
||||
|
||||
msgid ""
|
||||
"By default the stock overview page lists all products which are currently in"
|
||||
" stock or below their min. stock amount - when this is enabled, all (active)"
|
||||
" products are always shown"
|
||||
msgstr ""
|
||||
msgstr "默认情况下,库存概览页面列出所有当前有库存或低于最低库存量的产品 - 启用此选项后,将始终显示所有(活动的)产品"
|
||||
|
||||
msgid "No price information is available for at least one ingredient"
|
||||
msgstr ""
|
||||
msgstr "至少有一种配料没有价格信息"
|
||||
|
||||
msgid ""
|
||||
"For ingredients that are only partially in stock, the in stock amount will "
|
||||
"be consumed."
|
||||
msgstr ""
|
||||
msgstr "对于部分有库存的配料,将消耗库存数量。"
|
||||
|
||||
msgid "Can't be opened"
|
||||
msgstr ""
|
||||
msgstr "无法开封"
|
||||
|
||||
msgid "Default purchase price type"
|
||||
msgstr ""
|
||||
msgstr "默认购买价格类型"
|
||||
|
||||
msgid "This will be used as the default price type selection on purchase"
|
||||
msgstr ""
|
||||
msgstr "这将用作购买时的默认价格类型选择"
|
||||
|
||||
msgid "Unspecified"
|
||||
msgstr ""
|
||||
msgstr "未指定"
|
||||
|
||||
msgid "Round up quantity amounts to the nearest whole number"
|
||||
msgstr ""
|
||||
msgstr "将数量四舍五入到最接近的整数"
|
||||
|
||||
msgid "Stock actions"
|
||||
msgstr ""
|
||||
msgstr "库存操作"
|
||||
|
||||
msgid "List actions"
|
||||
msgstr ""
|
||||
msgstr "列表操作"
|
||||
|
||||
msgid "Reports"
|
||||
msgstr "报表"
|
||||
|
||||
msgid "Last Used"
|
||||
msgstr "上次使用"
|
||||
|
||||
msgid "Last Used Report"
|
||||
msgstr "闲置物品报告"
|
||||
|
||||
msgid "Amount in stock"
|
||||
msgstr "库存数量"
|
||||
|
|
|
|||
35
migrations/0255.sql
Normal file
35
migrations/0255.sql
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
-- Add common Chinese quantity units
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('克', '克', 'gram');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('斤', '斤', 'jin (500g)');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('公斤', '公斤', 'kilogram');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('个', '个', 'piece/item');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('包', '包', 'pack');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('瓶', '瓶', 'bottle');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('罐', '罐', 'can/jar');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('升', '升', 'liter');
|
||||
INSERT INTO quantity_units (name, name_plural, description) VALUES ('毫升', '毫升', 'milliliter');
|
||||
|
||||
-- Add conversions between them
|
||||
-- 1 jin = 500 gram
|
||||
INSERT INTO quantity_unit_conversions (from_qu_id, to_qu_id, factor)
|
||||
SELECT from_qu.id, to_qu.id, 500
|
||||
FROM quantity_units from_qu, quantity_units to_qu
|
||||
WHERE from_qu.name = '斤' AND to_qu.name = '克';
|
||||
|
||||
-- 1 kilogram = 1000 gram
|
||||
INSERT INTO quantity_unit_conversions (from_qu_id, to_qu_id, factor)
|
||||
SELECT from_qu.id, to_qu.id, 1000
|
||||
FROM quantity_units from_qu, quantity_units to_qu
|
||||
WHERE from_qu.name = '公斤' AND to_qu.name = '克';
|
||||
|
||||
-- 1 kilogram = 2 jin
|
||||
INSERT INTO quantity_unit_conversions (from_qu_id, to_qu_id, factor)
|
||||
SELECT from_qu.id, to_qu.id, 2
|
||||
FROM quantity_units from_qu, quantity_units to_qu
|
||||
WHERE from_qu.name = '公斤' AND to_qu.name = '斤';
|
||||
|
||||
-- 1 liter = 1000 milliliter
|
||||
INSERT INTO quantity_unit_conversions (from_qu_id, to_qu_id, factor)
|
||||
SELECT from_qu.id, to_qu.id, 1000
|
||||
FROM quantity_units from_qu, quantity_units to_qu
|
||||
WHERE from_qu.name = '升' AND to_qu.name = '毫升';
|
||||
20
public/viewjs/stockreportlastused.js
Normal file
20
public/viewjs/stockreportlastused.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
var stockLastUsedTable = $('#stock-last-used-table').DataTable({
|
||||
'order': [[2, 'asc']], // Order by 'Last used' date by default
|
||||
'columnDefs': [
|
||||
{ 'orderable': false, 'targets': 0 },
|
||||
{ 'searchable': false, "targets": 0 }
|
||||
].concat($.fn.dataTable.defaults.columnDefs)
|
||||
});
|
||||
$('#stock-last-used-table tbody').removeClass("d-none");
|
||||
stockLastUsedTable.columns.adjust().draw();
|
||||
|
||||
$("#search").on("keyup", Delay(function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
if (value === "all")
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
stockLastUsedTable.search(value).draw();
|
||||
}, Grocy.FormFocusDelay));
|
||||
|
|
@ -64,6 +64,7 @@ $app->group('', function (RouteCollectorProxy $group)
|
|||
$group->get('/stockentry/{entryId}/label', '\Grocy\Controllers\StockController:StockEntryGrocycodeLabel');
|
||||
$group->get('/quantityunitconversionsresolved', '\Grocy\Controllers\StockController:QuantityUnitConversionsResolved');
|
||||
$group->get('/stockreports/spendings', '\Grocy\Controllers\StockReportsController:Spendings');
|
||||
$group->get('/stockreports/lastused', '\Grocy\Controllers\StockReportsController:LastUsed');
|
||||
|
||||
// Stock price tracking
|
||||
$group->get('/shoppinglocations', '\Grocy\Controllers\StockController:ShoppingLocationsList');
|
||||
|
|
|
|||
|
|
@ -273,6 +273,34 @@
|
|||
</li>
|
||||
@endif
|
||||
|
||||
<div class="nav-item-divider"></div>
|
||||
<li class="nav-item nav-item-sidebar"
|
||||
data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
title="{{ $__t('Reports') }}">
|
||||
<a class="nav-link nav-link-collapse discrete-link collapsed"
|
||||
data-toggle="collapse"
|
||||
href="#sub-nav-reports">
|
||||
<i class="fa-solid fa-fw fa-chart-line"></i>
|
||||
<span class="nav-link-text">{{ $__t('Reports') }}</span>
|
||||
</a>
|
||||
<ul id="sub-nav-reports"
|
||||
class="sidenav-second-level collapse">
|
||||
<li>
|
||||
<a class="nav-link discrete-link"
|
||||
href="{{ $U('/stockreports/spendings') }}">
|
||||
<span class="nav-link-text">{{ $__t('Spendings') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="nav-link discrete-link"
|
||||
href="{{ $U('/stockreports/lastused') }}">
|
||||
<span class="nav-link-text">{{ $__t('Last Used') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_STOCK)
|
||||
<div class="nav-item-divider"></div>
|
||||
<li class="nav-item nav-item-sidebar permission-STOCK_PURCHASE @if($viewName == 'purchase') active-page @endif"
|
||||
|
|
|
|||
50
views/stockreportlastused.blade.php
Normal file
50
views/stockreportlastused.blade.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
@extends('layout.default')
|
||||
|
||||
@section('title', $__t('Last Used Report'))
|
||||
@section('viewJsName', 'stockreportlastused')
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h2 class="title">@yield('title')</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-2">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-8 pb-3">
|
||||
<div class="table-responsive">
|
||||
<table id="stock-last-used-table" class="table table-striped dt-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ $__t('Product') }}</th>
|
||||
<th>{{ $__t('Amount in stock') }}</th>
|
||||
<th>{{ $__t('Last used') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="d-none">
|
||||
@foreach($products as $product)
|
||||
<tr>
|
||||
<td>
|
||||
{{ $product->name }}
|
||||
</td>
|
||||
<td>
|
||||
{{ $product->amount }}
|
||||
</td>
|
||||
<td>
|
||||
@if($product->last_used)
|
||||
{{ $product->last_used }}
|
||||
<time class="timeago timeago-contextual" datetime="{{ $product->last_used }}"></time>
|
||||
@else
|
||||
{{ $__t('Never') }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Loading…
Reference in New Issue
Block a user