115 lines
4.6 KiB
Python
115 lines
4.6 KiB
Python
import datetime
|
|
from flask import Blueprint, request, jsonify
|
|
from flask_jwt_extended import jwt_required, get_jwt_identity
|
|
from .database import db, MilkBatch, User
|
|
from .utils import calculate_expiry_date, convert_volume
|
|
|
|
milk_bp = Blueprint('milk', __name__, url_prefix='/api/milk')
|
|
|
|
@milk_bp.route('', methods=['POST'])
|
|
@jwt_required()
|
|
def add_milk():
|
|
current_user_id = get_jwt_identity()
|
|
data = request.get_json()
|
|
if not data: return jsonify({"error": "Request must be JSON"}), 400
|
|
|
|
expiry_date_str = data.get('expiryDate')
|
|
production_date_str = data.get('productionDate')
|
|
shelf_life = data.get('shelfLife')
|
|
shelf_unit = data.get('shelfUnit', 'days')
|
|
initial_quantity_items = data.get('quantity')
|
|
volume_per_item = data.get('volumePerItem')
|
|
volume_unit = data.get('unit') # 'ml' or 'L'
|
|
note = data.get('note')
|
|
|
|
# --- Validation ---
|
|
if not initial_quantity_items or volume_per_item is None or not volume_unit:
|
|
return jsonify({"error": "Missing required fields: quantity, volumePerItem, unit"}), 400
|
|
if volume_unit not in ['ml', 'L']:
|
|
return jsonify({"error": "Invalid volume unit. Use 'ml' or 'L'."}), 400
|
|
try:
|
|
initial_quantity_items = int(initial_quantity_items)
|
|
volume_per_item = float(volume_per_item)
|
|
if initial_quantity_items <= 0 or volume_per_item <= 0:
|
|
raise ValueError("Quantity and volume must be positive.")
|
|
except (ValueError, TypeError):
|
|
return jsonify({"error": "Invalid number format for quantity or volumePerItem."}), 400
|
|
|
|
# --- Determine Expiry Date ---
|
|
expiry_date = None
|
|
if expiry_date_str:
|
|
try:
|
|
expiry_date = datetime.date.fromisoformat(expiry_date_str)
|
|
except ValueError:
|
|
return jsonify({"error": "Invalid expiryDate format. Use YYYY-MM-DD."}), 400
|
|
elif production_date_str and shelf_life:
|
|
expiry_date = calculate_expiry_date(production_date_str, shelf_life, shelf_unit)
|
|
if not expiry_date:
|
|
return jsonify({"error": "Invalid productionDate or shelfLife for expiry calculation."}), 400
|
|
else:
|
|
return jsonify({"error": "Either expiryDate or (productionDate and shelfLife) is required."}), 400
|
|
|
|
# --- Production Date (Optional) ---
|
|
prod_date = None
|
|
if production_date_str:
|
|
try:
|
|
prod_date = datetime.date.fromisoformat(production_date_str)
|
|
except ValueError:
|
|
# Allow if only expiry date was provided, otherwise error
|
|
if not expiry_date_str:
|
|
return jsonify({"error": "Invalid productionDate format. Use YYYY-MM-DD."}), 400
|
|
|
|
# --- Create Batch ---
|
|
initial_remaining_volume = initial_quantity_items * volume_per_item
|
|
new_batch = MilkBatch(
|
|
user_id=current_user_id,
|
|
production_date=prod_date,
|
|
expiry_date=expiry_date,
|
|
initial_quantity_items=initial_quantity_items,
|
|
volume_per_item=volume_per_item,
|
|
volume_unit=volume_unit,
|
|
note=note,
|
|
remaining_volume=initial_remaining_volume,
|
|
is_deleted=False
|
|
)
|
|
db.session.add(new_batch)
|
|
try:
|
|
db.session.commit()
|
|
return jsonify(new_batch.to_dict()), 201
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
print(f"Error adding milk batch: {e}")
|
|
return jsonify({"error": "Database error occurred."}), 500
|
|
|
|
@milk_bp.route('', methods=['GET'])
|
|
@jwt_required()
|
|
def get_milk_batches():
|
|
current_user_id = get_jwt_identity()
|
|
include_deleted = request.args.get('includeDeleted', 'false').lower() == 'true'
|
|
only_active = request.args.get('onlyActive', 'true').lower() == 'true' # Only not empty and not expired
|
|
|
|
query = MilkBatch.query.filter_by(user_id=current_user_id)
|
|
|
|
if not include_deleted:
|
|
query = query.filter_by(is_deleted=False)
|
|
|
|
if only_active:
|
|
query = query.filter(MilkBatch.remaining_volume > 0.001) # Check remaining volume with tolerance
|
|
query = query.filter(MilkBatch.expiry_date >= datetime.date.today())
|
|
|
|
|
|
# Sort by expiry date (soonest first)
|
|
batches = query.order_by(MilkBatch.expiry_date.asc()).all()
|
|
return jsonify([batch.to_dict() for batch in batches]), 200
|
|
|
|
@milk_bp.route('/<int:batch_id>', methods=['DELETE'])
|
|
@jwt_required()
|
|
def delete_milk_batch(batch_id):
|
|
current_user_id = get_jwt_identity()
|
|
batch = MilkBatch.query.filter_by(id=batch_id, user_id=current_user_id).first()
|
|
if not batch: return jsonify({"error": "Milk batch not found or access denied."}), 404
|
|
if batch.is_deleted: return jsonify({"message": "Batch already deleted."}), 200
|
|
|
|
batch.is_deleted = True # Soft delete
|
|
db.session.commit()
|
|
return '', 204 |