267 lines
16 KiB
Python
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()
|