import datetime import uuid from fastapi import APIRouter, Depends, Request, Security from sqlalchemy.orm import Session, joinedload_all from sqlalchemy.sql.expression import and_, func, or_ from ...core.security import get_current_active_user as get_user from ...core.session import get_finish_date, get_start_date, set_period from ...db.session import SessionLocal from ...models.master import AccountBase from ...models.voucher import Journal, Voucher, VoucherType from ...schemas.auth import UserToken router = APIRouter() # Dependency def get_db() -> Session: try: db = SessionLocal() yield db finally: db.close() @router.get("") def show_blank( request: Request, user: UserToken = Security(get_user, scopes=["reconcile"]), ): return { "startDate": get_start_date(request.session), "finishDate": get_finish_date(request.session), "account": None, "body": [], } @router.get("/{id_}") def show_data( id_: uuid.UUID, request: Request, s: str = None, f: str = None, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["reconcile"]), ): account = db.query(AccountBase).filter(AccountBase.id == id_).first() start_date = s if s is not None else get_start_date(request.session) finish_date = f if f is not None else get_finish_date(request.session) body = build_report(account.id, start_date, finish_date, db) set_period(start_date, finish_date, request.session) return { "startDate": start_date, "finishDate": finish_date, "account": {"id": account.id, "name": account.name}, "body": body, } def build_report(account_id, start_date, finish_date, db): opening = opening_balance(account_id, start_date, db) body = [opening] query = ( db.query(Voucher) .options(joinedload_all(Voucher.journals, Journal.account, innerjoin=True)) .filter(Voucher.journals.any(Journal.account_id == account_id)) .filter( or_( Voucher.is_reconciled == False, and_( Voucher.reconcile_date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"), Voucher.reconcile_date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"), ), ) ) .filter(Voucher.type != VoucherType.by_name("Issue").id) .order_by(Voucher.is_reconciled) .order_by(Voucher.reconcile_date) .order_by(Voucher.last_edit_date) .all() ) for voucher in query: debit = 0 credit = 0 journal_debit = 0 name = "" for journal in voucher.journals: if journal.account_id == account_id: journal_debit = journal.debit if journal.debit == 1: debit = journal.amount credit = 0 else: credit = journal.amount debit = 0 for journal in voucher.journals: if journal.debit != journal_debit: name += "{0} / ".format(journal.account.name) name = name[:-3] body.append( { "id": voucher.id, "date": voucher.date.strftime("%d-%b-%Y"), "name": name, "type": VoucherType.by_id(voucher.type).name, "narration": voucher.narration, "debit": debit, "credit": credit, "isReconciled": voucher.is_reconciled, "reconcileDate": voucher.reconcile_date.strftime("%d-%b-%Y"), } ) return body def opening_balance(account_id, start_date, db): opening = ( db.query(func.sum(Journal.amount * Journal.debit)) .join(Journal.voucher) .filter( Voucher.reconcile_date < datetime.datetime.strptime(start_date, "%d-%b-%Y") ) .filter(Voucher.is_reconciled == True) .filter(Voucher.type != VoucherType.by_name("Issue").id) .filter(Journal.account_id == account_id) .scalar() ) opening = 0 if opening is None else opening if opening < 0: credit = opening * -1 debit = 0 else: debit = opening credit = 0 return { "date": start_date, "id": None, "name": "Opening Balance", "type": "Opening Balance", "narration": "", "debit": debit, "credit": credit, "running": opening, "isReconciled": True, "reconcileDate": start_date, } @router.post("/{id_}") def save( id_: uuid.UUID, request: Request, s: str = None, f: str = None, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["reconcile"]), ): account = db.query(AccountBase).filter(AccountBase.id == id_).first() start_date = s if s is not None else get_start_date(request.session) finish_date = f if f is not None else get_finish_date(request.session) raise Exception("not fixed") # for item in request.json_body["body"]: # if "id" not in item or item["id"] is None: # continue # # voucher = ( # request.dbsession.query(Voucher) # .filter(Voucher.id == uuid.UUID(item["id"])) # .first() # ) # is_reconciled = item["isReconciled"] # reconcile_date = datetime.datetime.strptime(item["reconcileDate"], "%d-%b-%Y") # voucher.is_reconciled = is_reconciled # voucher.reconcile_date = reconcile_date # transaction.commit() # body = build_report(account.id, start_date, finish_date, request) # return { # "startDate": start_date, # "finishDate": finish_date, # "account": {"id": account.id, "name": account.name}, # "body": body # }