import arrow from decimal import Decimal from datetime import datetime from time import perf_counter from sqlalchemy import select, func, distinct, cast, Date, String, literal, desc, and_, or_, case, join, alias, text from interest_calculate import hesapla_gecikme_faizi from Controllers.Postgres.engine import get_session_factory from Schemas import ( BuildDecisionBookPayments, AccountRecords, ApiEnumDropdown, Build, BuildDecisionBook, AccountDelayInterest, BuildParts, ) # from ServicesApi.Schemas.account.account import AccountRecords, AccountDelayInterest # from ServicesApi.Schemas.building.decision_book import BuildDecisionBookPayments, BuildDecisionBook # from ServicesApi.Schemas.building.build import Build, BuildParts # from ServicesApi.Schemas.others.enums import ApiEnumDropdown """ BuildDuesTypes BDT-S Service fee (Service fee) BuildDuesTypes BDT-I Information (Information) BuildDuesTypes BDT-D Bina Aidat (Debit) BuildDuesTypes BDT-A Bina Ek Aidat (Add Debit) BuildDuesTypes BDT-R Bina Tadilat (Renovation) BuildDuesTypes BDT-L Bina Yasal Harcama (Lawyer expence) BuildDuesTypes BDT-CL Close Last Period Receipt (Close Last Period Receipt) BuildDuesTypes BDT-OP Open New Period Receipt (Open New Period Receipt) """ def joined_decision_book_sql_query(build_decision_book_id: int=49): subquery = select( AccountRecords.build_parts_id, BuildParts.part_code, BuildParts.part_no, AccountRecords.build_decision_book_id, func.sum(AccountRecords.currency_value).label('paid') ).select_from( AccountRecords.__table__.join( BuildParts, AccountRecords.build_parts_id == BuildParts.id ) ).where( AccountRecords.build_decision_book_id == build_decision_book_id ).group_by( AccountRecords.build_parts_id, BuildParts.part_code, BuildParts.part_no, AccountRecords.build_decision_book_id ).alias('build_parts_to_account_records') query = select( subquery.c.build_decision_book_id, subquery.c.build_parts_id, subquery.c.part_code, subquery.c.part_no, subquery.c.paid, func.sum(BuildDecisionBookPayments.payment_amount).label('debt'), (func.sum(BuildDecisionBookPayments.payment_amount) + subquery.c.paid).label('total') ).select_from( subquery.join( BuildDecisionBookPayments, (BuildDecisionBookPayments.build_parts_id == subquery.c.build_parts_id) & (BuildDecisionBookPayments.build_decision_book_id == subquery.c.build_decision_book_id) ) ).group_by( subquery.c.build_decision_book_id, subquery.c.build_parts_id, subquery.c.part_code, subquery.c.part_no, subquery.c.paid ).order_by( subquery.c.part_no ) return query def print_query_result_like_dateabse_rows(results, book_id, expiry_starts, expiry_ends): start_time = perf_counter() print(f"\nResults for build_decision_book_id={book_id}:") print(f"Selected decision book starts at: {expiry_starts} - ends at: {expiry_ends}") print("-" * 80) print(f"{'Build ID':<10} {'Parts ID':<10} {'Part Code':<15} {'Part No':<10} {'Paid (odenen)':<15} {'Debt (borc)':<15} {'Total':<15}") print("-" * 80) for row in results: print(f"{row.build_decision_book_id:<10} {row.build_parts_id:<10} {row.part_code:<15} {row.part_no:<10} {row.paid:<15.2f} {row.debt:<15.2f} {row.total:<15.2f}") print("-" * 80) print(f"Total rows: {len(results)}") print(f"Query execution time: {perf_counter() - start_time:.4f} seconds") if __name__ == "__main__": """ Waiting for container to be ready... Running the Python script inside the container... Old book ID: 49 New book ID: 50 Old book starts at: 2024-07-01 - ends at: 2025-06-30 New book starts at: 2025-07-01 - ends at: 2026-06-30 Done! Check the output above. """ session_factory = get_session_factory() session = session_factory() start_time = perf_counter() Build.set_session(session) BuildDecisionBook.set_session(session) build_decision_book_id, timezone = 49, "Europe/Istanbul" selected_decision_book = BuildDecisionBook.query.filter_by(id=build_decision_book_id).first() old_expiry_starts = arrow.get(selected_decision_book.expiry_starts).to(timezone).date() old_expiry_ends = arrow.get(selected_decision_book.expiry_ends).to(timezone).date() old_book_id = selected_decision_book.id results = BuildDecisionBook.query.filter( BuildDecisionBook.build_id == selected_decision_book.build_id, BuildDecisionBook.expiry_ends > old_expiry_ends).order_by(BuildDecisionBook.expiry_ends.asc() ).all() new_book = results[0] if len(results) > 0 else None if not new_book: raise ValueError(f"New book not found after => {build_decision_book_id}. Contant your admin for future updates") new_expiry_starts = arrow.get(new_book.expiry_starts).to(timezone).date() new_expiry_ends = arrow.get(new_book.expiry_ends).to(timezone).date() new_book_id = new_book.id joined_query = joined_decision_book_sql_query(build_decision_book_id=build_decision_book_id) results = session.execute(joined_query).fetchall() print_query_result_like_dateabse_rows(results=results, book_id=old_book_id, expiry_starts=old_expiry_starts, expiry_ends=old_expiry_ends) for result in results: if result.total > 0: print(f'User has extra money in old book {result.total} | build part id : {result.build_parts_id} | part code : {result.part_code} | part no : {result.part_no}') elif result.total < 0: print(f'User has debt in new book {result.total} | build part id : {result.build_parts_id} | part code : {result.part_code} | part no : {result.part_no}') else: print(f'User has no debt or extra money in old book {result.total} | build part id : {result.build_parts_id} | part code : {result.part_code} | part no : {result.part_no}') session.close() # print(f"Old book ID: {old_book_id}") # print(f"New book ID: {new_book_id}") # print(f"New book starts at: {new_expiry_starts} - ends at: {new_expiry_ends}") # old_account_records = session.query(func.sum(AccountRecords.currency_value) - func.sum(BuildDecisionBookPayments.payment_amount)).filter( # old_expiry_starts <= cast(AccountRecords.bank_date, Date), old_expiry_ends >= cast(AccountRecords.bank_date, Date), # AccountRecords.currency_value > 0, # func.abs(AccountRecords.currency_value) > func.abs(BuildDecisionBookPayments.payment_amount) # ).scalar() # new_account_records = session.query(func.sum(AccountRecords.currency_value) - func.sum(BuildDecisionBookPayments.payment_amount)).filter( # new_expiry_starts <= cast(AccountRecords.bank_date, Date), new_expiry_ends >= cast(AccountRecords.bank_date, Date), # AccountRecords.currency_value > 0, # func.abs(AccountRecords.currency_value) > func.abs(BuildDecisionBookPayments.payment_amount) # ).scalar() # print(f"Old account records: {old_account_records:,.2f}") # print(f"New account records: {new_account_records:,.2f}") # build_to_iterate = Build.query.filter_by(id=build_id).first() # iterate_decision_books = BuildDecisionBook.query.filter_by(build_id=build_to_iterate.id).all() # for decision_book_to_iterate in iterate_decision_books: # joined_query = joined_decision_book_sql_query(build_decision_book_id=decision_book_to_iterate.id) # print(f"Build Decision Book ID: {decision_book_to_iterate.id}") # results = session.execute(joined_query).fetchall() # print(f"\nResults for build_decision_book_id={decision_book_to_iterate.id}:") # print("-" * 80) # print(f"{'Build ID':<10} {'Parts ID':<10} {'Part Code':<15} {'Part No':<10} {'Paid (odenen)':<15} {'Debt (borc)':<15}") # print("-" * 80) # for row in results: # print(f"{row.build_decision_book_id:<10} {row.build_parts_id:<10} {row.part_code:<15} {row.part_no:<10} {row.odenen:<15.2f} {row.borc:<15.2f}") # print("-" * 80) # print(f"Total rows: {len(results)}") # print(f"Query execution time: {perf_counter() - start_time:.4f} seconds") # print(f"\nResults for build_decision_book_id={build_decision_book_id}:") # print(f"Selected decision book starts at: {old_expiry_starts} - ends at: {old_expiry_ends}") # print("-" * 80) # print(f"{'Build ID':<10} {'Parts ID':<10} {'Part Code':<15} {'Part No':<10} {'Paid (odenen)':<15} {'Debt (borc)':<15}") # print("-" * 80) # for row in results: # print(f"{row.build_decision_book_id:<10} {row.build_parts_id:<10} {row.part_code:<15} {row.part_no:<10} {row.odenen:<15.2f} {row.borc:<15.2f}") # print("-" * 80) # print(f"Total rows: {len(results)}") # print(f"Query execution time: {perf_counter() - start_time:.4f} seconds")