"""Logic for Ledger Reserve Release Schedule.""" from abacus_common_logic.connectors.database import db from owsresponse import response from werkzeug.exceptions import abort from ledger.constants.error import ( ERROR_POST_REQUEST_DUPLICATE_RECORDS, ERROR_RECORD_ALREADY_EXISTS, ERROR_UNKNOWN_CURRENCY, ) from ledger.models.ledger_reserve_release_schedule import LedgerReserveReleaseSchedule from ledger.schemas.ledger_reserve_release_schedule import ( LedgerReserveReleaseScheduleDetailSchema, LedgerReserveReleaseScheduleExtendedSchema, ) from ledger.utils.currency import currency_exists existing_ledger_records_schema = LedgerReserveReleaseScheduleDetailSchema( many=True, only=( 'abacus_event_id', 'account_id', 'taken_statement_period_id', 'release_statement_period_id', 'ledger_reserve_taken_id', ), ) def bulk_create(request): """Bulk create logic.""" new_ledger_reserve_release_schedules = list() _validate_post_request_data(request) existing_ledger_records = _get_existing_ledger_records(request) for record in request: validate_record(record) _has_existing_ledger_record(record, existing_ledger_records) new_release_schedule = LedgerReserveReleaseSchedule.build(**record) new_ledger_reserve_release_schedules.append(new_release_schedule) db.session.commit() return response.Response( message=LedgerReserveReleaseScheduleDetailSchema(many=True).dump( new_ledger_reserve_release_schedules ), status=201, ) def get_by_release_statement_period_id(release_statement_period_id): """Get Ledger Reserve Release Schedule items by statement period.""" items = LedgerReserveReleaseSchedule.get_by_release_statement_period_id( release_statement_period_id ) return response.Response( message=LedgerReserveReleaseScheduleExtendedSchema(many=True).dump(items) ) def validate_record(record): """Validate record.""" if not currency_exists(record.get('currency_code')): abort( status=400, description=ERROR_UNKNOWN_CURRENCY.format(code=record.get('currency_code')), ) def _validate_post_request_data(request_body: list): """Validate if post request body contains unique records. Args: request_body (list): POST request body """ list_of_unique_records = list() request_data = existing_ledger_records_schema.dump(request_body) for record in request_data: if record in list_of_unique_records: abort( status=400, description=ERROR_POST_REQUEST_DUPLICATE_RECORDS.format(record), ) else: list_of_unique_records.append(record) def _has_existing_ledger_record(new_post_record: dict, existing_records: list): """Check if record already exist in ledger_reserve_release_schedule table or not.""" record = dict( abacus_event_id=new_post_record['abacus_event_id'], account_id=new_post_record['account_id'], taken_statement_period_id=new_post_record['taken_statement_period_id'], release_statement_period_id=new_post_record['release_statement_period_id'], ledger_reserve_taken_id=new_post_record['ledger_reserve_taken_id'], ) if record in existing_records: abort(status=409, description=ERROR_RECORD_ALREADY_EXISTS.format(record)) def _get_existing_ledger_records(records: list) -> list: """Get existing ledger_reserve_release_schedule records. Args: records (list): POST request body Returns: returns existing ledger_reserve_release_schedule records """ ledger_reserve_taken_ids = list( set([record['ledger_reserve_taken_id'] for record in records]) ) results = LedgerReserveReleaseSchedule.get_by_ledger_reserve_taken_ids( ledger_reserve_taken_ids ) return existing_ledger_records_schema.dump(results)