from datetime import datetime, timezone, timedelta from app.extensions import db from app.models.charge import Charge from sqlalchemy.orm import relationship from sqlalchemy.sql import func from sqlalchemy.exc import IntegrityError from app.utils.logger import logger class Payments(db.Model): __tablename__ = 'payments' id = db.Column( db.Integer, primary_key=True, autoincrement=True, ) uid = db.Column(db.String(150), nullable=True) member_id = db.Column(db.Integer, nullable=False) option_name = db.Column(db.String(100), nullable=False) option_type = db.Column(db.String(25), nullable=False) payment_uid = db.Column(db.String(100), nullable=False) amount = db.Column(db.Integer, nullable=True, default=0) status = db.Column(db.Integer, nullable=True, default=1) added = db.Column(db.DateTime(timezone=True), server_default=func.now()) sub_start = db.Column(db.DateTime(timezone=True)) next_billing = db.Column(db.DateTime(timezone=True)) sub_stop = db.Column(db.DateTime(timezone=True)) ''' "payment_uid": currentPaymentsession.uid, "member_id": currentPaymentsession.member_id, "option_name": currentPaymentsession.option_name, "amount": amount_subtotal, "option_type": "MAIN" ''' @classmethod def add_payment(cls, member_id, payment_uid, option_name,amount, option_type, next_billing_days=30): # Get the current date and time current_date = datetime.now() # Calculate the date "next_billing_days" days from now next_billing_date = current_date + timedelta(days=next_billing_days) # Save the response pay_data = cls( member_id=member_id, payment_uid=payment_uid, option_name=option_name, amount=amount, option_type=option_type, added=datetime.now(timezone.utc), sub_start=datetime.now(timezone.utc), next_billing = next_billing_date ) try: db.session.add(pay_data) except IntegrityError as err: raise ValueError(f"Database integrity error: {err}") return pay_data @classmethod def get_member_payments_by_member_id(cls, member_id): member_payments = cls.query.filter_by(member_id=str(member_id)) if not member_payments: return None return member_payments @classmethod def get_all_payments(cls, option_name=None, member_id=None, page=1, limit=20): query = cls.query logger.info(f"Get all payments back") if member_id: query = query.filter(cls.member_id == member_id) if option_name: query = query.filter(cls.option_name == option_name) # Order by created_at descending (newest first) query = query.order_by(cls.added.desc()) # Get total count before pagination total_count = query.count() # Apply pagination offset = (page - 1) * limit query = query.limit(limit).offset(offset) return query.all(), total_count def to_dict(self): return { "id": self.id, "uid": self.uid, "member_id": self.member_id, "option_name": self.option_name, "option_type": self.option_type, "payment_uid": self.payment_uid, "amount": self.amount, "status": self.status, "added": self.added, "sub_start": self.sub_start, "next_billing": self.next_billing, "sub_stop": self.sub_stop } def __repr__(self): return f''