"""Contract Flowthrough handlers.""" from abacus_common_logic.constants.error import ERROR_ENTITY_DOES_NOT_EXIST from abacus_common_logic.views.create_view import CreateView from abacus_common_logic.views.item_view import ItemView from flask import Blueprint, request from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from abacus_contract.constants import error from abacus_contract.logic import ( contract as contract_logic, contract_flowthrough as logic, ) from abacus_contract.models.contract_flowthrough import ContractFlowthrough from abacus_contract.schemas.contract_flowthrough import ( ContractFlowthroughDetailSchema, ContractFlowthroughPostSchema, ContractFlowthroughPutSchema, ) from abacus_contract.utils import authorization from abacus_contract.utils.dataloader import account_scoped_dataloader contract_flowthrough_api = Blueprint('contract_flowthrough_api', __name__) class ContractFlowthroughItemView(ItemView): """View for existing contract_flowthrough.""" model_class = ContractFlowthrough object_detail_schema = ContractFlowthroughDetailSchema() put_schema = ContractFlowthroughPutSchema() def get(self, object_id): """Find object by its id or return an error.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) obj = self.model_class.get_by_id(object_id) if not obj or (obj.deleted_at is not None or obj.deleted_by is not None): return flaskify( response.create_not_found_response( message=ERROR_ENTITY_DOES_NOT_EXIST.format( object_type='ContractFlowthrough', object_id=object_id ) ) ) body = self.object_detail_schema.dump(obj) return flaskify(response.Response(message=body, status=200)) def delete(self, object_id): """Delete a contract_flowthrough.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) obj = self.model_class.get_by_id_or_error(object_id, 404) return flaskify(logic.soft_delete_contract_flowthrough(obj)) def put(self, object_id, **kwargs): """Update contract_flowthrough by id.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) obj = self.model_class.get_by_id(object_id) if not obj or (obj.deleted_at is not None or obj.deleted_by is not None): return flaskify( response.create_not_found_response( message=ERROR_ENTITY_DOES_NOT_EXIST.format( object_type='ContractFlowthrough', object_id=object_id ) ) ) return super().put(object_id, **kwargs) def update_handler(self, obj, **params): """Handle contract_flowthrough updates.""" return logic.update_contract_flowthrough(obj, **params) contract_flowthrough_api.add_url_rule( '/contract-flowthrough//', methods=['GET', 'DELETE', 'PUT'], view_func=ContractFlowthroughItemView.as_view('contract_flowthrough'), ) class ContractFlowthroughCreateView(CreateView): """Handles contract_flowthrough creation.""" post_schema = ContractFlowthroughPostSchema() def post(self, **kwargs): """Create a contract_flowthrough.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message='Unauthorized', status=401, ) ) return super().post(**kwargs) def create_handler(self, **params): """Handle contract_flowthrough creation.""" return logic.create_contract_flowthrough(**params) contract_flowthrough_api.add_url_rule( '/contract//contract-flowthrough/', view_func=ContractFlowthroughCreateView.as_view('create_contract_flowthrough'), ) @contract_flowthrough_api.route( '/contract//contract-flowthrough/', methods=['GET'] ) def get_contract_flowthrough_by_contract_id(contract_id: int): """GET a contract_flowthrough by contract_id. Arg: contract_id(int): id of the contract """ access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: account_id = contract_logic.get_account_id_by_contract_id(contract_id) if not account_id: # Can't verify that user has access to something we can't find return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) authorized = authorization.pdp_authorize_many_accounts( [account_id], ) if not authorized: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) return flaskify(logic.get_contract_flowthrough_by_contract_id(contract_id)) @contract_flowthrough_api.route('/contract-flowthroughs/dataloader', methods=['POST']) def get_flowthroughs_by_contract_ids_dataloader(): """Batch-fetch contract flowthroughs for the given contract_ids.""" return account_scoped_dataloader( entity_name='Contract', resolve_accounts=contract_logic.get_account_id_map_by_contract_ids, fetch_records=logic.get_flowthrough_records_by_contract_ids, key_field='contract_id', as_list=False, )