138 lines
4.7 KiB
Python
138 lines
4.7 KiB
Python
import os
|
|
from flask import Blueprint, render_template, request, redirect, url_for, jsonify, current_app
|
|
from flask_login import login_required, current_user
|
|
from werkzeug.utils import secure_filename
|
|
from core.db import get_db_connection
|
|
from core.utils import download_image
|
|
from core.events import socketio
|
|
|
|
inventory_bp = Blueprint('inventory', __name__)
|
|
|
|
@inventory_bp.route('/inventory')
|
|
@login_required
|
|
def inventory():
|
|
with get_db_connection() as conn:
|
|
products = conn.execute('SELECT * FROM products').fetchall()
|
|
return render_template('inventory.html', active_page='inventory', products=products, user=current_user)
|
|
|
|
@inventory_bp.route("/upsert", methods=["POST"])
|
|
@login_required
|
|
def upsert():
|
|
d = request.form
|
|
barcode = d['barcode']
|
|
|
|
price_str = d.get('price', '0')
|
|
stock_str = d.get('stock', '0')
|
|
|
|
try:
|
|
price = float(price_str) if price_str else 0.0
|
|
stock = float(stock_str) if stock_str else 0.0
|
|
except (ValueError, TypeError):
|
|
price = 0.0
|
|
stock = 0.0
|
|
|
|
name = d.get('name', '')
|
|
image_url = d.get('image_url', '')
|
|
unit_type = d.get('unit_type', 'unit')
|
|
|
|
cache_dir = current_app.config['CACHE_DIR']
|
|
final_image_path = download_image(image_url, barcode, cache_dir)
|
|
|
|
with get_db_connection() as conn:
|
|
conn.execute('''INSERT INTO products (barcode, name, price, image_url, stock, unit_type)
|
|
VALUES (?,?,?,?,?,?)
|
|
ON CONFLICT(barcode) DO UPDATE SET
|
|
name=excluded.name,
|
|
price=excluded.price,
|
|
image_url=excluded.image_url,
|
|
stock=excluded.stock,
|
|
unit_type=excluded.unit_type''',
|
|
(barcode, name, price, final_image_path, stock, unit_type))
|
|
conn.commit()
|
|
return redirect(url_for('inventory.inventory'))
|
|
|
|
@inventory_bp.route('/upload_image', methods=['POST'])
|
|
@login_required
|
|
def upload_image():
|
|
if 'image' not in request.files:
|
|
return jsonify({"error": "No image file provided"}), 400
|
|
|
|
file = request.files['image']
|
|
barcode = request.form.get('barcode', '')
|
|
|
|
if not barcode:
|
|
return jsonify({"error": "No barcode provided"}), 400
|
|
|
|
if file.filename == '':
|
|
return jsonify({"error": "Empty file"}), 400
|
|
|
|
cache_dir = current_app.config['CACHE_DIR']
|
|
ext = '.jpg'
|
|
local_filename = f"{secure_filename(barcode)}{ext}"
|
|
local_path = os.path.join(cache_dir, local_filename)
|
|
|
|
file.save(local_path)
|
|
|
|
image_url = f"/static/cache/{local_filename}"
|
|
return jsonify({"image_url": image_url}), 200
|
|
|
|
@inventory_bp.route('/delete/<barcode>', methods=['POST'])
|
|
@login_required
|
|
def delete(barcode):
|
|
cache_dir = current_app.config['CACHE_DIR']
|
|
|
|
with get_db_connection() as conn:
|
|
conn.execute('DELETE FROM products WHERE barcode = ?', (barcode,))
|
|
conn.commit()
|
|
|
|
img_p = os.path.join(cache_dir, f"{barcode}.jpg")
|
|
if os.path.exists(img_p): os.remove(img_p)
|
|
if socketio:
|
|
socketio.emit('product_deleted', {"barcode": barcode})
|
|
return redirect(url_for('inventory.inventory'))
|
|
|
|
@inventory_bp.route('/bulk_price_update', methods=['POST'])
|
|
@login_required
|
|
def bulk_price_update():
|
|
data = request.get_json()
|
|
barcodes = data.get('barcodes', [])
|
|
new_price = data.get('new_price')
|
|
|
|
if not barcodes or new_price is None:
|
|
return jsonify({"error": "Missing data"}), 400
|
|
|
|
try:
|
|
with get_db_connection() as conn:
|
|
params = [(float(new_price), b) for b in barcodes]
|
|
conn.executemany('UPDATE products SET price = ? WHERE barcode = ?', params)
|
|
conn.commit()
|
|
return jsonify({"status": "success"}), 200
|
|
except Exception as e:
|
|
print(f"Bulk update failed: {e}")
|
|
return jsonify({"error": str(e)}), 500
|
|
|
|
@inventory_bp.route('/bulk_delete', methods=['POST'])
|
|
@login_required
|
|
def bulk_delete():
|
|
cache_dir = current_app.config['CACHE_DIR']
|
|
|
|
data = request.get_json()
|
|
barcodes = data.get('barcodes', [])
|
|
|
|
if not barcodes:
|
|
return jsonify({"error": "No barcodes provided"}), 400
|
|
|
|
try:
|
|
with get_db_connection() as conn:
|
|
conn.execute(f'DELETE FROM products WHERE barcode IN ({",".join(["?"]*len(barcodes))})', barcodes)
|
|
conn.commit()
|
|
|
|
for barcode in barcodes:
|
|
img_p = os.path.join(cache_dir, f"{barcode}.jpg")
|
|
if os.path.exists(img_p):
|
|
os.remove(img_p)
|
|
|
|
return jsonify({"status": "success"}), 200
|
|
except Exception as e:
|
|
print(f"Bulk delete failed: {e}")
|
|
return jsonify({"error": str(e)}), 500 |