"""Blueprint for statement period API.""" from abacus_common_logic.views.item_view import ItemView from abacus_common_logic.views.list_view import ListView from flask import Blueprint, request from owsrequest import flask_request from owsresponse import response from owsresponse.adaptors.flask import flaskify from royalties.constants import error from royalties.logic import statement_period as logic from royalties.models import StatementPeriod from royalties.schemas import StatementPeriodDetailSchema from royalties.utils import authorization from royalties.utils.format_error import validation_error from royalties.utils.request import get_optional_numeric_list_from_params statement_period_api = Blueprint('statement_period_api', __name__) @statement_period_api.route('/statement-periods/recent', methods=['GET']) def get_recent_statement_periods(): """Handle getting recent statement periods.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: authorized = authorization.pdp_authorize_resource( # This resource type is all-or-nothing, permissions-wise, # so id doesn't matter resource_id=0, resource_type='statement_period', ) 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_recent_statement_periods()) @statement_period_api.route('/statement-periods/upcoming', methods=['GET']) def get_upcoming_statement_periods(): """Handle getting upcoming statement periods.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: authorized = authorization.pdp_authorize_resource( # This resource type is all-or-nothing, permissions-wise, # so id doesn't matter resource_id=0, resource_type='statement_period', ) 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_upcoming_statement_periods()) @statement_period_api.route('/statement-period/current', methods=['GET']) def get_current_statement_period(): """Handle getting current statement period.""" 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 flaskify(logic.get_current_statement_period()) @statement_period_api.route( '/statement-period//close', methods=['PUT'] ) def close_statement_period(statement_period_id): """Handle closing specified statement period.""" 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 flaskify(logic.close_statement_period(statement_period_id)) class StatementPeriodItemView(ItemView): """View for finding statement period by ID.""" model_class = StatementPeriod object_detail_schema = StatementPeriodDetailSchema() def get(self, object_id, **kwargs): """Find statement period by 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, ) ) return super().get(object_id, **kwargs) class StatementPeriodListView(ListView): """View for listing statement periods.""" model_class = StatementPeriod list_entry_schema = StatementPeriodDetailSchema() def get(self): """Get a list of statement periods.""" access_rule_decision = flask_request.verify_rules_access_standalone(request) if not access_rule_decision: authorized = authorization.pdp_authorize_resource( # This resource type is all-or-nothing, permissions-wise, # so id doesn't matter resource_id=0, resource_type='statement_period', ) if not authorized: return flaskify( response.create_error_response( code=error.ERROR_CODE_AUTHORIZATION, message=error.ERROR_MESSAGE_FORBIDDEN_USER, status=403, ) ) return super().get() statement_period_api.add_url_rule( '/statement-period/', methods=['GET'], view_func=StatementPeriodItemView.as_view('statement_period'), ) @statement_period_api.route( '/statement-period//bulk-exchange-rates', methods=['GET'] ) def bulk_get_exchange_rates(statement_period_id: int): """Get bulk exchange rates.""" 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, ) ) output_format = request.args.get('format', 'json') result = logic.get_statement_period_exchange_rates( statement_period_id, output_format ) return flaskify(result) statement_period_api.add_url_rule( '/statement-periods/', methods=['GET'], view_func=StatementPeriodListView.as_view('list_statement_periods'), ) @statement_period_api.route('/statement-periods/', methods=['POST']) def get_statement_periods_by_years(): """Get statement periods by a list of statement_years. NOTE: This endpoint uses a POST method to allow for a larger list of query args. """ 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, ) ) try: statement_years = get_optional_numeric_list_from_params() except ValueError: return flaskify(validation_error(error.ERROR_INVALID_STATEMENT_YEARS)) return flaskify(logic.get_statement_periods_by_years(statement_years))