wag-managment-api-service-v.../service_account_records/app_accounts.py

342 lines
14 KiB
Python

import sys
if "/service_account_records" not in list(sys.path):
sys.path.append("/service_account_records")
from decimal import Decimal
from api_services.bank_actions.wag_account_record_parser import (
parse_comment_with_name,
parse_comment_with_name_iban_description,
)
from databases import (
AccountRecords,
BuildIbans,
BuildDecisionBook,
Build,
BuildLivingSpace,
People,
OccupantTypes,
)
from api_validations.validations_request import ListOptions
from api_library.date_time_actions.date_functions import system_arrow
from databases.sql_models.building.build import BuildParts
from databases.sql_models.building.decision_book import BuildDecisionBookPayments
from databases.sql_models.others.enums import ApiEnumDropdown
account_list = ListOptions(
page=1,
size=1000,
order_field="bank_date",
order_type="desc",
)
def account_records_find_decision_book():
created_ibans, iban_build_dict = [], {}
AccountRecords.filter_attr = account_list
account_records_list: list[AccountRecords] = AccountRecords.filter_all(
AccountRecords.build_decision_book_id == None,
AccountRecords.remainder_balance < AccountRecords.currency_value,
system=True,
).data
for account_record in account_records_list:
if account_record.iban not in created_ibans:
found_iban: BuildIbans = BuildIbans.filter_one(
BuildIbans.iban == account_record.iban, system=True
).data
if not found_iban:
try:
create_build_ibans = BuildIbans.find_or_create(
iban=account_record.iban,
start_date=str(system_arrow.now().shift(days=-1)),
)
create_build_ibans.save_and_confirm()
created_ibans.append(account_record.iban)
except Exception as e:
print("Exception of find_decision_book ln:55", e)
if not getattr(found_iban, "build_id", None): # It is in database already
iban_build_dict["iban"] = account_record.iban
iban_build_dict["build_id"] = None
else:
found_decision_book = BuildDecisionBook.filter_one(
BuildDecisionBook.build_id == found_iban.build_id,
BuildDecisionBook.expiry_starts <= account_record.bank_date,
BuildDecisionBook.expiry_ends > account_record.bank_date,
).data
if found_decision_book:
account_record.update(
build_decision_book_id=found_decision_book.id,
build_decision_book_uu_id=str(found_decision_book.uu_id),
build_id=found_decision_book.build_id,
build_uu_id=str(found_decision_book.build_uu_id),
)
account_record.save()
return
def account_save_search_result(account_record, similarity_result):
found_company = similarity_result.get("company", None)
found_customer, part, build = (
similarity_result.get("living_space", None),
None,
None,
)
if found_customer:
part = BuildParts.filter_by_one(
id=found_customer.build_parts_id, human_livable=True
).data
if part:
build = Build.filter_by_one(id=part.build_id).data
account_record.similarity = similarity_result.get("similarity", 0.00)
account_record.found_from = similarity_result.get("found_from", None)
account_record.company_id = getattr(found_company, "id", None)
account_record.company_uu_id = getattr(found_company, "uu_id", None)
account_record.build_parts_id = getattr(part, "id", None)
account_record.build_parts_uu_id = getattr(part, "uu_id", None)
if not account_record.build_id and build:
account_record.build_id = getattr(build, "id", None)
account_record.build_uu_id = getattr(build, "uu_id", None)
# account_record.send_person_id = getattr(found_send_person, "id", None)
# account_record.send_person_uu_id = getattr(found_send_person, "uu_id", None)
account_record.living_space_id = getattr(found_customer, "id", None)
account_record.living_space_uu_id = getattr(found_customer, "uu_id", None)
account_record.save()
def account_get_people_and_living_space_info_via_iban() -> dict:
build_living_space_dict = {}
account_records_ibans = (
AccountRecords.select_only(
AccountRecords.build_decision_book_id != None,
select_args=[AccountRecords.iban],
system=True,
)
.query.distinct(AccountRecords.iban)
.all()
)
flat_resident = OccupantTypes.filter_by_one(
system=True, occupant_category_type="FL", occupant_code="FL-RES"
).data
flat_owner = OccupantTypes.filter_by_one(
system=True, occupant_category_type="FL", occupant_code="FL-OWN"
).data
flat_tenant = OccupantTypes.filter_by_one(
system=True, occupant_category_type="FL", occupant_code="FL-TEN"
).data
flat_represent = OccupantTypes.filter_by_one(
system=True, occupant_category_type="FL", occupant_code="FL-REP"
).data
for account_records_iban in account_records_ibans:
if account_records_iban not in build_living_space_dict:
build_iban: BuildIbans = BuildIbans.filter_one(
BuildIbans.iban == account_records_iban[0], system=True
).data
build_parts = BuildParts.filter_by_all(
system=True, build_id=build_iban.build_id, human_livable=True
).data
living_spaces = BuildLivingSpace.filter_all(
BuildLivingSpace.build_parts_id.in_(
[build_parts.id for build_parts in build_parts]
),
BuildLivingSpace.occupant_type.in_(
[flat_resident.id, flat_owner.id, flat_tenant.id, flat_represent.id]
),
).data
living_spaces_people = [
living_space.person_id
for living_space in living_spaces
if living_space.person_id
]
people_list = People.filter_all(
People.id.in_(living_spaces_people), system=True
).data
print("build_parts", build_parts)
build_living_space_dict[str(account_records_iban[0])] = {
"people": list(people_list),
"living_space": list(living_spaces),
"build_parts": list(build_parts),
}
return build_living_space_dict
def account_records_search():
build_living_space_dict = account_get_people_and_living_space_info_via_iban()
AccountRecords.filter_attr, found_list = account_list, []
account_records_list: list[AccountRecords] = AccountRecords.filter_all(
# AccountRecords.build_decision_book_id != None, system=True
).data
for account_record in account_records_list:
similarity_result = parse_comment_with_name(
account_record=account_record, living_space_dict=build_living_space_dict
)
fs, ac = similarity_result.get("similarity"), account_record.similarity or 0
if float(fs) >= 0.8 and float(fs) > float(ac):
found_list.append(similarity_result)
account_save_search_result(
account_record=account_record, similarity_result=similarity_result
)
else:
similarity_result = parse_comment_with_name_iban_description(
account_record=account_record
)
fs, ac = similarity_result.get("similarity"), account_record.similarity or 0
if float(fs) >= 0.8 and float(fs) > float(ac):
found_list.append(similarity_result)
account_save_search_result(
account_record=account_record, similarity_result=similarity_result
)
print("Account Records Search : ", len(found_list), "/", len(account_records_list))
return
def pay_the_registration(
account_record, receive_enum, debit_enum, is_old_record: bool = False
):
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 = system_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.filter_all(*payment_arguments_debit)
.query.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.filter_all(*payment_arguments_receive).data or []
)
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 = system_arrow.get(payment.process_date)
try:
created_book_payment = BuildDecisionBookPayments.find_or_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():
AccountRecords.filter_attr = account_list
receive_enum = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-R"
).data
debit_enum = ApiEnumDropdown.filter_by_one(
system=True, enum_class="DebitTypes", key="DT-D"
).data
account_records_list: list[AccountRecords] = AccountRecords.filter_all(
AccountRecords.remainder_balance < AccountRecords.currency_value,
AccountRecords.approved_record == True,
AccountRecords.receive_debit == receive_enum.id,
).data
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_records_find_decision_book()
account_records_search()
send_accounts_to_decision_payment()
print("Account Records Service is finished...")
return
if __name__ == "__main__":
account_records_service()