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