EzSplit / database.py
santu24's picture
Commit Files
83fb89d
import os
from datetime import datetime
import pymongo
from urllib.parse import quote_plus
from bson.objectid import ObjectId
raw_username = os.getenv("DB_USERNAME")
raw_password = os.getenv("DB_PASSWORD")
if not raw_username or not raw_password:
raise Exception("Database credentials are missing. Check your environment variables.")
username = quote_plus(raw_username)
password = quote_plus(raw_password)
cluster = "cluster0.yxjok.mongodb.net"
DB_URI = f"mongodb+srv://{username}:{password}@{cluster}/?retryWrites=true&w=majority&appName=Cluster0"
client = pymongo.MongoClient(DB_URI)
db = client["billing_app"]
users_coll = db["users"]
sections_coll = db["sections"]
bills_coll = db["bills"]
sections_coll.create_index(
[("owner_email", 1), ("section_name", 1)],
unique=True
)
def create_user(email, password):
if users_coll.find_one({"email": email}):
raise ValueError("Email already exists")
users_coll.insert_one({"email": email, "password": password})
def get_user_by_email_and_password(email, password):
return users_coll.find_one({"email": email, "password": password})
def create_section(owner_email, section_name, participants_list):
"""
Creates a new section for the given user.
Fails if that user already has a section with the same name.
"""
existing = sections_coll.find_one({"owner_email": owner_email, "section_name": section_name})
if existing:
raise ValueError("Section with this name already exists for your account.")
sections_coll.insert_one({
"owner_email": owner_email,
"section_name": section_name,
"participants": participants_list
})
def update_section(owner_email, section_name, participants_list):
sections_coll.update_one(
{"owner_email": owner_email, "section_name": section_name},
{"$set": {"participants": participants_list}},
upsert=True
)
def get_section(owner_email, section_name):
return sections_coll.find_one({"owner_email": owner_email, "section_name": section_name})
def delete_section(owner_email, section_name):
sections_coll.delete_one({"owner_email": owner_email, "section_name": section_name})
bills_coll.delete_many({"owner_email": owner_email, "section_name": section_name})
def get_all_sections(owner_email):
"""
Returns all sections for that specific user/email.
"""
sections = sections_coll.find({"owner_email": owner_email})
return [sec["section_name"] for sec in sections]
def create_bill(owner_email, section_name, participant, item, price):
bills_coll.insert_one({
"owner_email": owner_email,
"section_name": section_name,
"participant": participant,
"item": item,
"price": float(price),
"timestamp": datetime.now().date().isoformat()
})
def get_submitted_items(owner_email, section_name):
pipeline = [
{"$match": {"owner_email": owner_email, "section_name": section_name}},
{"$group": {"_id": "$item"}}
]
results = list(bills_coll.aggregate(pipeline))
return [r["_id"] for r in results]
def get_billing_history(owner_email, section_name):
pipeline = [
{"$match": {"owner_email": owner_email, "section_name": section_name}},
{
"$group": {
"_id": "$participant",
"total_price": {"$sum": "$price"},
"last_updated": {"$max": "$timestamp"}
}
}
]
return list(bills_coll.aggregate(pipeline))
def remove_items(owner_email, section_name, participant, items_to_remove):
if items_to_remove is None:
bills_coll.delete_many({
"owner_email": owner_email,
"section_name": section_name,
"participant": participant
})
else:
for item in items_to_remove:
bills_coll.delete_many({
"owner_email": owner_email,
"section_name": section_name,
"participant": participant,
"item": item
})
def get_most_bought_item(owner_email, section_name):
pipeline = [
{"$match": {"owner_email": owner_email, "section_name": section_name}},
{
"$group": {
"_id": "$item",
"count": {"$sum": 1},
"max_price": {"$max": "$price"}
}
},
{"$sort": {"count": -1, "max_price": -1}},
{"$limit": 1}
]
result = list(bills_coll.aggregate(pipeline))
if result:
return (result[0]["_id"], result[0]["count"], result[0]["max_price"])
return None