production-evyos-systems-an.../ServicesBank/Finder/app_accounts.py

267 lines
16 KiB
Python

import sys
import arrow
if "/service_account_records" not in list(sys.path):
sys.path.append("/service_account_records")
from decimal import Decimal
from pydantic import BaseModel
from typing import Optional, Union
from sqlalchemy import func, cast, Date
from Schemas import AccountRecords, BuildIbans, BuildDecisionBook, Build, BuildLivingSpace, People, OccupantTypes, BuildParts, BuildDecisionBookPayments, ApiEnumDropdown
from account_record_parser import parse_comment_with_name, parse_comment_with_name_iban_description
# from ServicesApi.Schemas.account.account import AccountRecords
# from ServicesApi.Schemas.building.build import BuildIbans, BuildDecisionBook, BuildParts, BuildLivingSpace, Build
# from ServicesApi.Schemas.identity.identity import People, OccupantTypes
# from ServicesApi.Schemas.others.enums import ApiEnumDropdown
# from ServicesApi.Schemas.building.decision_book import BuildDecisionBookPayments
# AccountRecords.approved_record = False
def account_find_build_from_iban(session):
created_ibans = []
AccountRecords.set_session(session)
BuildIbans.set_session(session)
account_records_ibans = AccountRecords.query.filter(AccountRecords.build_id == None, AccountRecords.approved_record == False).distinct(AccountRecords.iban).all()
for account_records_iban in account_records_ibans:
found_iban: BuildIbans = BuildIbans.query.filter(BuildIbans.iban == account_records_iban.iban).first()
if not found_iban:
create_build_ibans = BuildIbans.create(iban=account_records_iban.iban, start_date=str(arrow.now().shift(days=-1)))
create_build_ibans.save()
created_ibans.append(account_records_iban.iban)
else:
update_dict = {"build_id": found_iban.build_id, "build_uu_id": str(found_iban.build_uu_id)}
session.query(AccountRecords).filter(AccountRecords.iban == account_records_iban.iban).update(update_dict, synchronize_session=False)
session.commit()
def account_records_find_decision_book(session):
AccountRecords.set_session(session)
BuildIbans.set_session(session)
BuildDecisionBook.set_session(session)
created_ibans, iban_build_dict = [], {}
account_records_list: list[AccountRecords] = AccountRecords.query.filter(AccountRecords.build_id != None, AccountRecords.build_decision_book_id == None).order_by(AccountRecords.bank_date.desc()).all()
for account_record in account_records_list:
if found_iban := BuildIbans.query.filter(BuildIbans.iban == account_record.iban).first():
if found_decision_book := BuildDecisionBook.query.filter(
BuildDecisionBook.build_id == found_iban.build_id,
cast(BuildDecisionBook.expiry_starts, Date) <= cast(account_record.bank_date, Date),
cast(BuildDecisionBook.expiry_ends, Date) >= cast(account_record.bank_date, Date),
).first():
account_record.build_decision_book_id = found_decision_book.id
account_record.build_decision_book_uu_id = str(found_decision_book.uu_id)
account_record.save()
def account_get_people_and_living_space_info_via_iban() -> dict:
build_living_space_dict = {}
AccountRecords.set_session(session)
OccupantTypes.set_session(session)
BuildParts.set_session(session)
BuildLivingSpace.set_session(session)
People.set_session(session)
account_records_ibans = AccountRecords.query.filter(AccountRecords.build_decision_book_id != None).distinct(AccountRecords.iban).all()
flat_resident = OccupantTypes.query.filter_by(occupant_category_type="FL", occupant_code="FL-RES").first()
flat_owner = OccupantTypes.query.filter_by(occupant_category_type="FL", occupant_code="FL-OWN").first()
flat_tenant = OccupantTypes.query.filter_by(occupant_category_type="FL", occupant_code="FL-TEN").first()
flat_represent = OccupantTypes.query.filter_by(occupant_category_type="FL", occupant_code="FL-REP").first()
for account_records_iban in account_records_ibans:
if account_records_iban.iban not in build_living_space_dict:
build_parts = BuildParts.query.filter_by(build_id=account_records_iban.build_id, human_livable=True).all()
living_spaces = BuildLivingSpace.query.filter(
BuildLivingSpace.build_parts_id.in_([build_parts.id for build_parts in build_parts]),
BuildLivingSpace.occupant_type_id.in_([flat_resident.id, flat_owner.id, flat_tenant.id, flat_represent.id]),
).all()
living_spaces_people = [living_space.person_id for living_space in living_spaces if living_space.person_id]
people_list = People.query.filter(People.id.in_(living_spaces_people)).all()
people_list_dict = []
for people in people_list:
people_list_dict.append({"id": people.id, "uu_id": str(people.uu_id), "firstname": people.firstname, "surname": people.surname, "middle_name": people.middle_name})
living_spaces_dict = []
for living_space in living_spaces:
living_spaces_dict.append({"id": living_space.id, "uu_id": str(living_space.uu_id), "person_id": living_space.person_id, "person_uu_id": str(living_space.person_uu_id)})
build_parts_dict = []
for build_parts in build_parts:
build_parts_dict.append({"id": build_parts.id, "uu_id": str(build_parts.uu_id)})
build_living_space_dict[str(account_records_iban.iban)] = {"people": list(people_list_dict), "living_space": list(living_spaces_dict), "build_parts": list(build_parts_dict)}
return build_living_space_dict
def account_records_search():
build_living_space_dict = account_get_people_and_living_space_info_via_iban()
found_list = []
with AccountRecords.new_session() as session:
AccountRecords.set_session(session)
account_records_list: list[AccountRecords] = AccountRecords.query.filter(AccountRecords.build_decision_book_id != None).all()
for account_record in account_records_list:
account_record_dict = account_record.get_dict()
similarity_result = parse_comment_with_name(account_record=account_record_dict, living_space_dict=build_living_space_dict)
fs, ac = float(similarity_result.get("similarity", 0)), float(account_record_dict.get("similarity", 0))
if fs >= 0.8 and fs >= ac:
print("similarity_result positive", similarity_result)
found_list.append(similarity_result)
account_save_search_result(account_record=account_record_dict, similarity_result=similarity_result)
else:
similarity_result = parse_comment_with_name_iban_description(account_record=account_record_dict)
fs, ac = float(similarity_result.get("similarity", 0)), float(account_record_dict.get("similarity", 0))
if fs >= 0.8 and fs > ac:
print("similarity_result negative", similarity_result)
found_list.append(similarity_result)
account_save_search_result(account_record=account_record_dict, similarity_result=similarity_result)
print("Account Records Search : ", len(found_list), "/", len(account_records_list))
return
def account_save_search_result(account_record, similarity_result):
BuildParts.set_session(session)
Build.set_session(session)
BuildLivingSpace.set_session(session)
found_company = similarity_result.get("company", None)
found_customer, part, build = (similarity_result.get("living_space", None), None, None)
if found_customer:
found_living_space = BuildLivingSpace.query.filter_by(id=int(found_customer.get("id"))).first()
part = BuildParts.query.filter_by(id=found_living_space.build_parts_id, human_livable=True).first()
if part:
build = Build.query.filter_by(id=part.build_id).first()
account_record_dict = {
"similarity": similarity_result.get("similarity", 0.00),
"found_from": similarity_result.get("found_from", None),
"company_id": getattr(found_company, "id", None),
"company_uu_id": str(getattr(found_company, "uu_id", None)) if getattr(found_company, "uu_id", None) else None,
"build_parts_id": getattr(part, "id", None) if getattr(part, "id", None) else None,
"build_parts_uu_id": str(getattr(part, "uu_id", None)) if getattr(part, "uu_id", None) else None,
"living_space_id": getattr(found_customer, "id", None),
"living_space_uu_id": str(getattr(found_customer, "uu_id", None)) if getattr(found_customer, "uu_id", None) else None,
}
if not account_record.get("build_id") and build:
account_record_dict.update({"build_id": getattr(build, "id", None), "build_uu_id": str(getattr(build, "uu_id", None)) if getattr(build, "uu_id", None) else None})
AccountRecords.query.filter_by(uu_id=str(account_record.get("uu_id"))).update(account_record_dict)
session.commit()
def pay_the_registration(account_record, receive_enum, debit_enum, is_old_record: bool = False):
with AccountRecords.new_session() as session:
AccountRecords.set_session(session)
BuildDecisionBookPayments.set_session(session)
current_currency_value = float(Decimal(account_record.currency_value)) - float(Decimal(account_record.remainder_balance))
if not current_currency_value > 0:
return current_currency_value
process_date = arrow.get(account_record.bank_date)
account_bank_date_year, account_bank_date_month = (process_date.date().year, process_date.date().month)
payment_arguments_debit = [
BuildDecisionBookPayments.build_parts_id == account_record.build_parts_id,
BuildDecisionBookPayments.payment_types_id == debit_enum.id,
BuildDecisionBookPayments.account_records_id == None,
]
if not is_old_record:
payment_arguments_debit.extend([BuildDecisionBookPayments.process_date_y == int(account_bank_date_year), BuildDecisionBookPayments.process_date_m == int(account_bank_date_month)])
payments = BuildDecisionBookPayments.query.filter(*payment_arguments_debit).order_by(BuildDecisionBookPayments.process_date.asc()).all()
for payment in payments:
if not current_currency_value > 0:
return current_currency_value
payment_arguments_receive = [
BuildDecisionBookPayments.build_parts_id == account_record.build_parts_id,
BuildDecisionBookPayments.payment_plan_time_periods == payment.payment_plan_time_periods,
BuildDecisionBookPayments.payment_types_id == receive_enum.id,
BuildDecisionBookPayments.build_decision_book_item_id == payment.build_decision_book_item_id,
BuildDecisionBookPayments.decision_book_project_id == payment.decision_book_project_id,
BuildDecisionBookPayments.process_date == payment.process_date,
]
if not is_old_record:
payment_arguments_receive.extend([BuildDecisionBookPayments.process_date_y == int(account_bank_date_year), BuildDecisionBookPayments.process_date_m == int(account_bank_date_month)])
payment_received = BuildDecisionBookPayments.query.filter(*payment_arguments_receive).all()
sum_of_payment_received = sum([abs(payment.payment_amount) for payment in payment_received])
net_amount = float(abs(Decimal(payment.payment_amount))) - float(abs(Decimal(sum_of_payment_received)))
if not net_amount > 0:
continue
if float(abs(current_currency_value)) < float(abs(net_amount)):
net_amount = float(current_currency_value)
process_date = arrow.get(payment.process_date)
try:
found_payment = BuildDecisionBookPayments.query.filter_by(
build_parts_id=payment.build_parts_id,
payment_plan_time_periods=payment.payment_plan_time_periods,
payment_types_id=receive_enum.id,
build_decision_book_item_id=payment.build_decision_book_item_id,
decision_book_project_id=payment.decision_book_project_id,
process_date=str(process_date),
).first()
if found_payment:
continue
created_book_payment = BuildDecisionBookPayments.create(
payment_plan_time_periods=payment.payment_plan_time_periods,
payment_amount=float(abs(net_amount)),
payment_types_id=receive_enum.id,
payment_types_uu_id=str(receive_enum.uu_id),
process_date=str(process_date),
process_date_m=process_date.date().month,
process_date_y=process_date.date().year,
period_time=f"{process_date.year}-{str(process_date.month).zfill(2)}",
build_parts_id=payment.build_parts_id,
build_parts_uu_id=str(payment.build_parts_uu_id),
account_records_id=account_record.id,
account_records_uu_id=str(account_record.uu_id),
build_decision_book_item_id=payment.build_decision_book_item_id,
build_decision_book_item_uu_id=str(payment.build_decision_book_item_uu_id),
decision_book_project_id=payment.decision_book_project_id,
decision_book_project_uu_id=str(payment.decision_book_project_uu_id),
)
created_book_payment.save_and_confirm()
created_payment_amount = float(Decimal(created_book_payment.payment_amount))
remainder_balance = float(Decimal(account_record.remainder_balance)) + float(abs(created_payment_amount))
account_record.update(remainder_balance=remainder_balance)
account_record.save()
if current_currency_value >= abs(net_amount):
current_currency_value -= abs(net_amount)
except Exception as e:
print("Exception of decision payment ln:300", e)
return current_currency_value
def send_accounts_to_decision_payment():
with ApiEnumDropdown.new_session() as session:
ApiEnumDropdown.set_session(session)
AccountRecords.set_session(session)
receive_enum = ApiEnumDropdown.query.filter_by(enum_class="DebitTypes", key="DT-R").first()
debit_enum = ApiEnumDropdown.query.filter_by(enum_class="DebitTypes", key="DT-D").first()
account_records_list: list[AccountRecords] = AccountRecords.query.filter(
AccountRecords.remainder_balance < AccountRecords.currency_value,
AccountRecords.approved_record == True,
AccountRecords.receive_debit == receive_enum.id,
).order_by(AccountRecords.bank_date.desc()).limit(1000).offset(0).all()
for account_record in account_records_list:
current_currency_value = pay_the_registration(account_record, receive_enum, debit_enum)
if current_currency_value > 0:
pay_the_registration(account_record, receive_enum, debit_enum, True)
if abs(float(Decimal(account_record.remainder_balance))) == abs(float(Decimal(account_record.currency_value))):
account_record.update(status_id=97)
account_record.save()
# # # todo If the payment is more than the amount, then create a new account record with the remaining amount
return
def account_records_service() -> None:
print("Account Records Service is running...")
account_find_build_from_iban(session=session)
account_records_find_decision_book(session=session)
account_records_search(session=session)
send_accounts_to_decision_payment(session=session)
print("Account Records Service is finished...")
if __name__ == "__main__":
account_records_service()