production-evyos-systems-an.../ServicesBank/Finder/Payment/draft
Berkay 9edc6cb6a0 updated payment service 2025-07-06 17:04:29 +03:00
..
completed.py updated Payment service 2025-06-30 21:34:16 +03:00
debug-payment.py updated Payment service 2025-06-30 21:34:16 +03:00
debug_remainder.py updated Payment service 2025-06-30 21:34:16 +03:00
draft-first-work.py updated Payment service 2025-06-30 21:34:16 +03:00
draft.py updated Payment service 2025-06-30 21:34:16 +03:00
old_runner_second.py updated payment service 2025-07-06 17:04:29 +03:00
old_running_code_with_case_added.py updated payment service 2025-07-06 17:04:29 +03:00
readme.py updated payment service 2025-07-06 17:04:29 +03:00
second.py updated Payment service 2025-06-30 21:34:16 +03:00
update_remainder_balance.py updated Payment service 2025-06-30 21:34:16 +03:00

readme.py

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")