Compare commits
2 Commits
2edbd6475f
...
0187f1d654
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0187f1d654 | ||
![]() |
a3bf47ecc3 |
42
app.py
42
app.py
@@ -1952,30 +1952,38 @@ def suggest_products():
|
||||
@app.route("/all_products")
|
||||
def all_products():
|
||||
sort = request.args.get("sort", "popularity")
|
||||
limit = request.args.get("limit", type=int) or 50
|
||||
limit = request.args.get("limit", type=int) or 100
|
||||
offset = request.args.get("offset", type=int) or 0
|
||||
|
||||
rows = db.session.query(Item.name, Item.list_id).distinct().all()
|
||||
ItemAlias = aliased(Item)
|
||||
SuggestedAlias = aliased(SuggestedProduct)
|
||||
|
||||
usage_map = defaultdict(set)
|
||||
original_names = {}
|
||||
base_query = db.session.query(
|
||||
func.lower(func.trim(ItemAlias.name)).label("normalized_name"),
|
||||
func.count(func.distinct(ItemAlias.list_id)).label("count"),
|
||||
func.min(ItemAlias.name).label("original_name")
|
||||
).join(
|
||||
SuggestedAlias,
|
||||
func.lower(func.trim(ItemAlias.name)) == func.lower(func.trim(SuggestedAlias.name))
|
||||
).group_by("normalized_name")
|
||||
|
||||
for raw_name, list_id in rows:
|
||||
norm = normalize_name(raw_name)
|
||||
usage_map[norm].add(list_id)
|
||||
if norm not in original_names or len(raw_name) < len(original_names[norm]):
|
||||
original_names[norm] = raw_name.strip()
|
||||
if sort == "popularity":
|
||||
base_query = base_query.order_by(func.count(func.distinct(ItemAlias.list_id)).desc(), "normalized_name")
|
||||
else:
|
||||
base_query = base_query.order_by("normalized_name")
|
||||
|
||||
counts = {k: len(v) for k, v in usage_map.items()}
|
||||
sorted_keys = sorted(
|
||||
counts.keys(),
|
||||
key=lambda k: (-counts[k], k) if sort == "popularity" else k
|
||||
)
|
||||
results = base_query.offset(offset).limit(limit).all()
|
||||
|
||||
paged_keys = sorted_keys[offset:offset + limit]
|
||||
products = [{"name": original_names[k], "count": counts[k]} for k in paged_keys]
|
||||
total_count = db.session.query(func.count()).select_from(
|
||||
base_query.subquery()
|
||||
).scalar()
|
||||
|
||||
return jsonify({"products": products, "total_count": len(counts)})
|
||||
products = [{"name": row.original_name, "count": row.count} for row in results]
|
||||
|
||||
return jsonify({
|
||||
"products": products,
|
||||
"total_count": total_count
|
||||
})
|
||||
|
||||
|
||||
@app.route("/upload_receipt/<int:list_id>", methods=["POST"])
|
||||
|
@@ -81,9 +81,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
|
||||
offset += limit;
|
||||
|
||||
if (productCountDisplay) {
|
||||
productCountDisplay.textContent = `Wyświetlono ${allProducts.length} produktów.`;
|
||||
}
|
||||
|
||||
const statsEl = document.getElementById('massAddProductStats');
|
||||
if (statsEl) {
|
||||
statsEl.textContent = `(${allProducts.length} z ${data.total_count})`;
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
const loadingEl = productList.querySelector('.loading');
|
||||
if (loadingEl) loadingEl.remove();
|
||||
|
@@ -223,7 +223,10 @@
|
||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||
<div class="modal-content bg-dark text-white">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="massAddModalLabel">Masowe dodawanie produktów</h5>
|
||||
<h5 class="modal-title" id="massAddModalLabel">
|
||||
Masowe dodawanie produktów
|
||||
<span id="massAddProductStats" class="ms-2 text-muted" style="font-size: 85%; font-weight: normal;"></span>
|
||||
</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Zamknij"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
Reference in New Issue
Block a user