"""StatementPeriodAdjustmentBatchCriteria logic.""" from abacus_common_logic.connectors.database import db from marshmallow import ValidationError from owsresponse import response from sqlalchemy import exc from werkzeug.exceptions import abort from royalties.constants.constants import STATEMENT_PERIOD_ADJUSTMENT_FILE_BATCH_TYPES from royalties.constants.error import ( ERROR_ADJUSTMENT_BATCH_CRITERIA_NOT_FOUND, ERROR_BATCH_CRITERIA_ALREADY_EXITS, ERROR_INTEGRITY_CONFLICT, ERROR_INVALID_DATA, ) from royalties.logic.statement_period_adjustment_file import ( _validate_statement_period_state, ) from royalties.models import ( StatementPeriodAdjustmentBatchCriteria, StatementPeriodAdjustmentFile, ) from royalties.schemas import ( StatementPeriodAdjustmentBatchCriteriaDetailSchema, StatementPeriodAdjustmentFileDetailSchema, ) from royalties.utils.format_error import validation_error def create_statement_period_adjustment_batch_criteria( statement_period_adjustment_file_id: int, batch_criteria: dict, ) -> response.Response: """Create statement period adjustment batch criteria. Args: statement_period_adjustment_file_id (int): ID of the statement_period_adjustment_file batch_criteria (dict): dict of attributes used to create adjustment batch. eg: {"payment_schedules": ["30_days_after_quarter_end"], "reference_payment_entities": [1,2,3]}.' Returns: an ows response """ StatementPeriodAdjustmentFile.get_by_id_or_error( statement_period_adjustment_file_id ) file_batch_criteria = StatementPeriodAdjustmentBatchCriteria.create( batch_criteria=batch_criteria, statement_period_adjustment_file_id=statement_period_adjustment_file_id, ) return response.Response( message=StatementPeriodAdjustmentBatchCriteriaDetailSchema().dump( file_batch_criteria ), status=201, ) def get_statement_period_adjustment_batch_criteria( statement_period_adjustment_file_id: int, ) -> response.Response: """Get the statement_period_adjustment_batch_criteria by file id. Args: statement_period_adjustment_file_id (int): ID of the statement_period_adjustment_file Returns: adjustment batch criteria details """ batch = StatementPeriodAdjustmentBatchCriteria.get_by_file_id( statement_period_adjustment_file_id ) if not batch: return response.Response( message=ERROR_ADJUSTMENT_BATCH_CRITERIA_NOT_FOUND.format( statement_period_adjustment_file_id ), status=404, ) return response.Response( message=StatementPeriodAdjustmentBatchCriteriaDetailSchema().dump(batch), status=200, ) def create_adjustment_file_and_batch_criteria( statement_period_id: int, batch_criteria: dict, file_name: str ) -> response.Response: """Create statement period adjustment file and batch criteria. Args: batch_criteria (dict): dict of attributes used to create adjustment batch. eg: {"payment_schedules": ["30_days_after_quarter_end"], "reference_payment_entities": [1,2,3]}.' file_name (str): name of the adjustment file statement_period_id (int): id of the statement period Returns: an ows response """ try: _validate_statement_period_state(statement_period_id) _ensure_unique_batch_criteria(batch_criteria, statement_period_id) except Exception as e: return validation_error(str(e)) try: new_adjustment_file = StatementPeriodAdjustmentFile.build( batch_type=STATEMENT_PERIOD_ADJUSTMENT_FILE_BATCH_TYPES.AUTO, file_name=file_name, statement_period_id=statement_period_id, ) db.session.flush() StatementPeriodAdjustmentBatchCriteria.build( batch_criteria=batch_criteria, statement_period_adjustment_file_id=new_adjustment_file.statement_period_adjustment_file_id, ) db.session.commit() except exc.IntegrityError: db.session.rollback() abort(status=409, description=ERROR_INTEGRITY_CONFLICT) except exc.DataError: db.session.rollback() abort(status=422, description=ERROR_INVALID_DATA) except Exception as e: db.session.rollback() raise e return response.Response( message=StatementPeriodAdjustmentFileDetailSchema().dump(new_adjustment_file), status=201, ) def _ensure_unique_batch_criteria( batch_criteria: dict, statement_period_id: int, ) -> None: """Verify whether an adjustment file with the specified batch criteria already exists within the given statement period. Args: batch_criteria (dict): dict of attributes used to create adjustment batch statement_period_id (int): id of the statement period """ existing_batch_criteria = ( StatementPeriodAdjustmentBatchCriteria.get_by_batch_criteria_and_period_id( batch_criteria, statement_period_id ) ) if len(existing_batch_criteria) > 0: raise ValidationError( ERROR_BATCH_CRITERIA_ALREADY_EXITS.format(statement_period_id) ) return