user moze edytowac paragony
This commit is contained in:
125
app.py
125
app.py
@@ -335,6 +335,31 @@ def _receipt_error(message):
|
||||
return redirect(request.referrer or url_for("main_page"))
|
||||
|
||||
|
||||
def rotate_receipt_by_id(receipt_id):
|
||||
receipt = Receipt.query.get_or_404(receipt_id)
|
||||
filepath = os.path.join(app.config["UPLOAD_FOLDER"], receipt.filename)
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
raise FileNotFoundError("Plik nie istnieje")
|
||||
|
||||
image = Image.open(filepath)
|
||||
rotated = image.rotate(-90, expand=True)
|
||||
rotated.save(filepath, format="WEBP", quality=100)
|
||||
return receipt
|
||||
|
||||
|
||||
def delete_receipt_by_id(receipt_id):
|
||||
receipt = Receipt.query.get_or_404(receipt_id)
|
||||
filepath = os.path.join(app.config["UPLOAD_FOLDER"], receipt.filename)
|
||||
|
||||
if os.path.exists(filepath):
|
||||
os.remove(filepath)
|
||||
|
||||
db.session.delete(receipt)
|
||||
db.session.commit()
|
||||
return receipt
|
||||
|
||||
|
||||
############# OCR ###########################
|
||||
|
||||
|
||||
@@ -739,6 +764,12 @@ def toggle_archive_list(list_id):
|
||||
@app.route("/edit_my_list/<int:list_id>", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def edit_my_list(list_id):
|
||||
receipts = (
|
||||
Receipt.query.filter_by(list_id=list_id)
|
||||
.order_by(Receipt.uploaded_at.desc())
|
||||
.all()
|
||||
)
|
||||
|
||||
l = db.session.get(ShoppingList, list_id)
|
||||
if l is None:
|
||||
abort(404)
|
||||
@@ -781,7 +812,7 @@ def edit_my_list(list_id):
|
||||
flash("Zaktualizowano dane listy", "success")
|
||||
return redirect(url_for("main_page"))
|
||||
|
||||
return render_template("edit_my_list.html", list=l)
|
||||
return render_template("edit_my_list.html", list=l, receipts=receipts)
|
||||
|
||||
|
||||
@app.route("/delete_user_list/<int:list_id>", methods=["POST"])
|
||||
@@ -1159,6 +1190,46 @@ def reorder_items():
|
||||
return jsonify(success=True)
|
||||
|
||||
|
||||
@app.route("/rotate_receipt/<int:receipt_id>")
|
||||
@login_required
|
||||
def rotate_receipt_user(receipt_id):
|
||||
receipt = Receipt.query.get_or_404(receipt_id)
|
||||
list_obj = ShoppingList.query.get_or_404(receipt.list_id)
|
||||
|
||||
if not (current_user.is_admin or current_user.id == list_obj.owner_id):
|
||||
flash("Brak uprawnień do tej operacji", "danger")
|
||||
return redirect(url_for("main_page"))
|
||||
|
||||
try:
|
||||
rotate_receipt_by_id(receipt_id)
|
||||
flash("Obrócono paragon", "success")
|
||||
except FileNotFoundError:
|
||||
flash("Plik nie istnieje", "danger")
|
||||
except Exception as e:
|
||||
flash(f"Błąd przy obracaniu: {str(e)}", "danger")
|
||||
|
||||
return redirect(request.referrer or url_for("main_page"))
|
||||
|
||||
|
||||
@app.route("/delete_receipt/<int:receipt_id>")
|
||||
@login_required
|
||||
def delete_receipt_user(receipt_id):
|
||||
receipt = Receipt.query.get_or_404(receipt_id)
|
||||
list_obj = ShoppingList.query.get_or_404(receipt.list_id)
|
||||
|
||||
if not (current_user.is_admin or current_user.id == list_obj.owner_id):
|
||||
flash("Brak uprawnień do tej operacji", "danger")
|
||||
return redirect(url_for("main_page"))
|
||||
|
||||
try:
|
||||
delete_receipt_by_id(receipt_id)
|
||||
flash("Paragon usunięty", "success")
|
||||
except Exception as e:
|
||||
flash(f"Błąd przy usuwaniu pliku: {str(e)}", "danger")
|
||||
|
||||
return redirect(request.referrer or url_for("main_page"))
|
||||
|
||||
|
||||
# OCR
|
||||
@app.route("/lists/<int:list_id>/analyze", methods=["POST"])
|
||||
@login_required
|
||||
@@ -1422,24 +1493,30 @@ def admin_receipts(id):
|
||||
@login_required
|
||||
@admin_required
|
||||
def rotate_receipt(receipt_id):
|
||||
receipt = Receipt.query.get_or_404(receipt_id)
|
||||
filepath = os.path.join(app.config["UPLOAD_FOLDER"], receipt.filename)
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
flash("Plik nie istnieje", "danger")
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
try:
|
||||
image = Image.open(filepath)
|
||||
rotated = image.rotate(-90, expand=True)
|
||||
rotated.save(filepath, format="WEBP", quality=85)
|
||||
rotate_receipt_by_id(receipt_id)
|
||||
flash("Obrócono paragon", "success")
|
||||
except FileNotFoundError:
|
||||
flash("Plik nie istnieje", "danger")
|
||||
except Exception as e:
|
||||
flash(f"Błąd przy obracaniu: {str(e)}", "danger")
|
||||
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
|
||||
@app.route("/admin/delete_receipt/<int:receipt_id>")
|
||||
@login_required
|
||||
@admin_required
|
||||
def delete_receipt(receipt_id):
|
||||
try:
|
||||
delete_receipt_by_id(receipt_id)
|
||||
flash("Paragon usunięty", "success")
|
||||
except Exception as e:
|
||||
flash(f"Błąd przy usuwaniu pliku: {str(e)}", "danger")
|
||||
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
|
||||
@app.route("/admin/rename_receipt/<int:receipt_id>")
|
||||
@login_required
|
||||
@admin_required
|
||||
@@ -1468,32 +1545,6 @@ def rename_receipt(receipt_id):
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
|
||||
@app.route("/admin/delete_receipt/<int:receipt_id>")
|
||||
@login_required
|
||||
@admin_required
|
||||
def delete_receipt(receipt_id):
|
||||
receipt = Receipt.query.get(receipt_id)
|
||||
if not receipt:
|
||||
flash("Paragon nie istnieje", "danger")
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
file_path = os.path.join(app.config["UPLOAD_FOLDER"], receipt.filename)
|
||||
|
||||
# Usuń plik
|
||||
if os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except Exception as e:
|
||||
flash(f"Błąd przy usuwaniu pliku: {str(e)}", "danger")
|
||||
|
||||
# Usuń rekord z bazy
|
||||
db.session.delete(receipt)
|
||||
db.session.commit()
|
||||
flash("Paragon usunięty", "success")
|
||||
|
||||
return redirect(request.referrer or url_for("admin_receipts", id="all"))
|
||||
|
||||
|
||||
@app.route("/admin/generate_receipt_hash/<int:receipt_id>")
|
||||
@login_required
|
||||
@admin_required
|
||||
|
@@ -47,9 +47,44 @@
|
||||
<button type="submit" class="btn btn-outline-success">Zapisz</button>
|
||||
<a href="{{ url_for('main_page') }}" class="btn btn-outline-light">Anuluj</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
{% if receipts %}
|
||||
<hr class="my-4">
|
||||
<h5>Paragony przypisane do tej listy</h5>
|
||||
|
||||
<div class="row">
|
||||
{% for r in receipts %}
|
||||
<div class="col-6 col-md-4 col-lg-3">
|
||||
<div class="card bg-dark text-white h-100">
|
||||
<a href="{{ url_for('uploaded_file', filename=r.filename) }}" class="glightbox" data-gallery="receipts"
|
||||
data-title="{{ r.filename }}">
|
||||
<img src="{{ url_for('uploaded_file', filename=r.filename) }}" class="card-img-top"
|
||||
style="object-fit: cover; height: 200px;">
|
||||
</a>
|
||||
<div class="card-body text-center">
|
||||
<p class="small text-truncate mb-1">{{ r.filename }}</p>
|
||||
<p class="small mb-1">Wgrano: {{ r.uploaded_at.strftime('%Y-%m-%d %H:%M') }}</p>
|
||||
{% if r.filesize and r.filesize >= 1024 * 1024 %}
|
||||
<p class="small mb-1">Rozmiar: {{ (r.filesize / 1024 / 1024) | round(2) }} MB</p>
|
||||
{% elif r.filesize %}
|
||||
<p class="small mb-1">Rozmiar: {{ (r.filesize / 1024) | round(1) }} kB</p>
|
||||
{% else %}
|
||||
<p class="small mb-1 text-muted">Brak danych o rozmiarze</p>
|
||||
{% endif %}
|
||||
|
||||
<a href="{{ url_for('rotate_receipt_user', receipt_id=r.id) }}"
|
||||
class="btn btn-sm btn-outline-warning w-100 mb-2">🔄 Obróć o 90°</a>
|
||||
|
||||
<a href="{{ url_for('delete_receipt_user', receipt_id=r.id) }}" class="btn btn-sm btn-outline-danger w-100"
|
||||
onclick="return confirm('Na pewno usunąć ten paragon?')">🗑️ Usuń</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr class="my-3">
|
||||
<!-- Trigger przycisk -->
|
||||
<div class="btn-group mt-4" role="group">
|
||||
|
Reference in New Issue
Block a user